# Improvement to debugging early errors when loading nodes

**URL:** https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197
**Category:** Feature Requests
**Created:** [18 July 2025 09:31 UTC](https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197 "2025-07-18T09:31:12Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [18 July 2025 09:31 UTC](https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197/1 "2025-07-18T09:31:12Z")

</div>

Hi, I managed to break something when messing around and I was reminded of an annoying oversight in `loader.js`.

Around lines 78 to 98, there are a couple of try/catch sections but the catch does not really show anything useful.

Here is an example from my recent log:

```auto
Welcome to Node-RED
===================
0|Node-RED |
18 Jul 10:19:34 - [info] Node-RED version: v4.1.0-beta.2
18 Jul 10:19:34 - [info] Node.js version: v22.15.0
18 Jul 10:19:34 - [info] Windows_NT 10.0.26100 x64 LE

18 Jul 10:19:35 - [info] Loading palette nodes
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at Object.dirname (node:path:739:5)
    at loadNodeLocales (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:234:35)
    at loadPluginConfig (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:331:11)
    at loadModuleTypeFiles (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:83:31)
    at loadModuleFiles (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:122:60)
    at load (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:43:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
  code: 'ERR_INVALID_ARG_TYPE'
}
18 Jul 10:19:35 - [info] Node-RED Contrib Theme Collection version: v4.0.11

```

As you can see, this does not tell me which node/plugin failed to load.

Thankfully, there is a very easy fix for this:

```js
            try {
                let promise;
                if (type === "nodes") {
                    promise = loadNodeConfig(things[thingName]);
                } else if (type === "plugins") {
                    promise = loadPluginConfig(things[thingName]);
                }
                promises.push(
                    promise.then(
                        (function() {
                            const n = thingName;
                            return function(nodeSet) {
                                things[n] = nodeSet;
                                return nodeSet;
                            }
                        })()
                    ).catch(err => {console.log(`"${thingName}"`, err)})
                );
            } catch(err) {
                console.log(`"${thingName}"`, err)
            }
        }

```

Notice the addition of `thingName` to the log output. Which means that we now get to see what node/plugin caused the issue:

```auto
Welcome to Node-RED
===================
0|Node-RED |
18 Jul 10:29:20 - [info] Node-RED version: v4.1.0-beta.2
18 Jul 10:29:20 - [info] Node.js version: v22.15.0
18 Jul 10:29:20 - [info] Windows_NT 10.0.26100 x64 LE

18 Jul 10:29:21 - [info] Loading palette nodes
"ti-dummy-runtime-plugin" TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at Object.dirname (node:path:739:5)
    at loadNodeLocales (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:234:35)
    at loadPluginConfig (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:331:11)
    at loadModuleTypeFiles (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:83:31)
    at loadModuleFiles (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:122:60)
    at load (D:\src\nr\node_modules\@node-red\registry\lib\loader.js:43:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
  code: 'ERR_INVALID_ARG_TYPE'
}
18 Jul 10:29:22 - [info] Node-RED Contrib Theme Collection version: v4.0.11

```

A nice easy fix. 😃

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [18 July 2025 10:28 UTC](https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197/2 "2025-07-18T10:28:00Z")

</div>

While debugging all this, I've also found some small bugs in `loader.js`.

I've tested both of the proposed fixes.

## `loadPluginConfig`

This function tries to set both `plugin.file` and `plugin.template`. At least one of these is needed for the call to `loadNodeLocales(plugin)`. This can fail if the plugin js is in a file `*.cjs` rather than `*.js` even though `*.cjs` is a perfectly valid filename.

At the least, I believe `loadPluginConfig` should throw a meaningful error if neither `file` nor `template` properties exist.

Ideally, the `*.js` file check should be expanded to look for `*.cjs` if the first check fails. Possibly also look for `*.mjs` if needed to allow for future use of modules.

Example fix:

```js
    var jsFile = file.replace(/\.[^.]+$/,".js");
    var htmlFile = file.replace(/\.[^.]+$/,".html");
    if (fs.existsSync(jsFile)) {
        plugin.file = jsFile;
    } else {
        jsFile = file.replace(/\.[^.]+$/,".cjs")
        if (fs.existsSync(jsFile)) {
            plugin.file = jsFile;
        }
    }
    if (fs.existsSync(htmlFile)) {
        plugin.template = htmlFile;
    }
    if (!plugin.file && !plugin.template) {
        throw new Error(`Plugin file not found: "${file}"`);
    }

    await loadNodeLocales(plugin)

```

## `loadNodeConfig`

This is a little simpler but fails for a similar but not quite identical issue. In this case, the `file` property is OK but the `template` property fails because, again, the `replace` assumes a source filename in the pattern `*.js`. This is actually an easier fix because we can easily extend the regex.

Old regex: `/\.js$/i`  
New regex: `/\.(js|cjs)$/i`

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [18 July 2025 10:44 UTC](https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197/3 "2025-07-18T10:44:47Z")

</div>

Please raise on github - either as an issue, or even a PR given you have proposed specific code changes. The forum isn't the place to report bugs.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [18 July 2025 10:47 UTC](https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197/4 "2025-07-18T10:47:20Z")

</div>

I wasn't sure it was a bug - the initial part is an enhancement request rather than a bug report.

However, I will report the bug.

Done:

> <https://github.com/node-red/node-red/issues/5220>
>
> \### Current Behavior
> 
> Reference: https://discourse.nodered.org/t/improvement-to-…debugging-early-errors-when-loading-nodes/98197
> 
> I've found some small bugs in loader.js.
> 
> I've tested both of the proposed fixes.
> 
> \## loadPluginConfig
> 
> This function tries to set both \`plugin.file\` and \`plugin.template\`. At least one of these is needed for the call to loadNodeLocales(plugin). This can fail if the plugin js is in a file \`\*.cjs\` rather than \`\*.js\` even though \`\*.cjs\` is a perfectly valid filename.
> 
> At the least, I believe \`loadPluginConfig\` should throw a meaningful error if neither file nor template properties exist.
> 
> Ideally, the \`\*.js\` file check should be expanded to look for \`\*.cjs\` if the first check fails. Possibly also look for \`\*.mjs\` if needed to allow for future use of modules.
> 
> Example fix:
> 
> \`\`\`js
> var jsFile = file.replace(/\\.\[^.\]+$/,".js");
> var htmlFile = file.replace(/\\.\[^.\]+$/,".html");
> if (fs.existsSync(jsFile)) {
> plugin.file = jsFile;
> } else {
> jsFile = file.replace(/\\.\[^.\]+$/,".cjs")
> if (fs.existsSync(jsFile)) {
> plugin.file = jsFile;
> }
> }
> if (fs.existsSync(htmlFile)) {
> plugin.template = htmlFile;
> }
> if (!plugin.file && !plugin.template) {
> throw new Error(\`Plugin file not found: "${file}"\`);
> }
> 
> await loadNodeLocales(plugin)
> \`\`\`
> 
> \## loadNodeConfig
> 
> This is a little simpler but fails for a similar but not quite identical issue. In this case, the file property is OK but the template property fails because, again, the replace assumes a source filename in the pattern \*.js. This is actually an easier fix because we can easily extend the regex.
> 
> Old regex: \`/\\.js$/i\`
> New regex: \`/\\.(js|cjs)$/i\`
> 
> \### Expected Behavior
> 
> The loader should be able to load both nodes and plugins having a file name \`\*.cjs\` (and possibly also \`\*.mjs\`).
> 
> \### Steps To Reproduce
> 
> Attempt to load a node or runtime plugin using \`cjs\` as the file extension.
> 
> \### Example flow
> 
> N/A
> 
> 
> \### Environment
> 
> \- Platform/OS: Windows 11
> \- Browser: N/A
> 
> \`\`\`
> 0|Node-RED | 18 Jul 11:26:57 - \[info\] Node-RED version: v4.1.0-beta.2
> 0|Node-RED | 18 Jul 11:26:57 - \[info\] Node.js version: v22.15.0
> 0|Node-RED | 18 Jul 11:26:57 - \[info\] Windows\_NT 10.0.26100 x64 LE
> \`\`\`

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [16 September 2025 10:48 UTC](https://discourse.nodered.org/t/improvement-to-debugging-early-errors-when-loading-nodes/98197/5 "2025-09-16T10:48:10Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
