Repository navigation
Missing import trace from error stack when loading a module throws an error #46992
Description
Activity
@nodejs/modules @nodejs/loaders
Reacted by Jacob SmithJakobJingleheimer commented
on Mar 8, 2023 on Mar 8, 2023 · Hidden as outdatedshow commentMore actions- addedesmIssues and PRs related to the ECMAScript Modules implementation.Issues and PRs related to the ECMAScript Modules implementation.loadersIssues and PRs related to ES module loaders.Issues and PRs related to ES module loaders.confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
on Mar 8, 2023 Gah, sorry, I misread my own output 🤦♂️
This may be fixed as part of #44710, which will most definitely change the stack-trace. I'll test there once all the tests are passing consistently.
in practice this inevitably breaks something else, so it’s completely unworkable.
What are the stack traces produced for the equivalent test case in Deno and in Chrome?
- removedconfirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
on Mar 12, 2023 This is the output from Deno (1.31.3), basically the same as Node:
error: Uncaught Error: bar failed throw new Error('bar failed'); ^ at file:///.../bar.mjs:1:7Chrome is also the same, but the key difference is that with Chrome you can at least go to the network tab and look at the "Initiators" list to see why something is being loaded. It's really clumsy (you have to manually search for it in the network tab and you can't double-click anything) and it lacks line numbers, but it's a start.
I don't use Deno but if a Deno user wants to raise a corresponding bug with them and link it here that would probably be a good idea.
If none of the runtimes are doing this, then it's a feature request rather than a bug. For me it also raises the question of what a stack trace is; I would think it should go to the line that threw the exception, as it does in the current traces, rather than the module that imported the line that threw the exception.
- addedfeature requestIssues requesting new Node.js features.Issues requesting new Node.js features.and removedloadersIssues and PRs related to ES module loaders.Issues and PRs related to ES module loaders.
on Mar 16, 2023 If none of the runtimes are doing this, then it's a feature request rather than a bug.
It's a very serious and major regression when compared with commonJS. People are shifting to pure ESM now and it's literally impossible to debug this kind of thing. This really needs to be sorted ASAP.
For me it also raises the question of what a stack trace is; I would think it should go to the line that threw the exception, as it does in the current traces, rather than the module that imported the line that threw the exception.
Obviously that should be the top of the stack. But the stack should not stop there, it needs context. Even if due to the technicalities of async module loading it might be requested from multiple places that doesn't change anything. If a module throws an exception we need to see why it was loaded and in what order.
Reacted by Felix Becker and Joshua Carter23 remaining items
One thing that you can do right now is this:
import 'data:text/javascript,console.log("hello");';It is very clumsy, but at least makes debugging imports possible by giving a way to add log messages within the import flow that don't get hoisted out of place.
This is documented at https://nodejs.org/api/esm.html#data-imports which is helpful.
I have opened a PR for this issue. Codecov and linting errors are resolved. Happy to discuss the implementation further.
Amazing! Is it possible to include the line number of the import statement?
Reacted by mattskelImport trace: file:///home/simon/github/node/baz.mjs imported by file:///home/simon/github/node/bar.mjs file:///home/simon/github/node/bar.mjs imported by file:///home/simon/github/node/foo.mjsIt also feels like this duplicates the filename unnecessarily. Possibly we don't need to include the module where the error was because it'll be in the stack trace?
Maybe something more like this?
Imported by: file:///home/simon/github/node/bar.mjs:1:1 file:///home/simon/github/node/foo.mjs:1:1Or this?
Import trace: file:///home/simon/github/node/baz.mjs imported by file:///home/simon/github/node/bar.mjs:1:1 imported by file:///home/simon/github/node/foo.mjs:1:1Also, the indentation should match stack traces, currently it's 2 spaces which is inconsistent.
Reacted by mattskel- added 2 commits that reference this issue
on Mar 2, 2026 @SystemParadox see recent changes
- Remove duplicate filenames.
- Add line and column info.
- Format indent.
That looks much neater.
I notice it doesn't support source maps - I've got a typescript project that gets compiled to
distwith esbuild and the error stack showssrc/xxx.ts, but the import trace showsdist/node/chunk-xxxxx.js.I'm not entirely sure what sourcemaps would even mean in this situation, maybe they don't even make sense for the import trace? If so then I'd suggest we should include the unmapped error line in the import trace, otherwise you can't see where the dist stack ends.
github-actions commented
on Jul 20, 2026 on Jul 20, 2026 – with GitHub ActionsContributorMore actionsThis issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jul 20, 2026 This is still relevant, we just have to figure out how best to show the trace when source maps are involved.
- removedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jul 21, 2026
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsAwaiting Triage
Version
v16.16.0
Platform
Linux 5.4.0-139-generic #156-Ubuntu SM x86_64 GNU/Linux
Subsystem
modules
What steps will reproduce the bug?
Consider:
Run
node foo.mjs.How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior?
The stack trace from the error should include a reference to
foo.mjsline 1 showing where bar was imported from.What do you see instead?
Note that the stack trace does not mention
fooanywhere. This is not helpful, especially if the error is specifically about how and whenbaris imported. For example, it might be a singleton and you're mistakenly creating a duplicate by loading it from bothimportandrequire, or it might need something else to be set up on the global first and you're loading it in the wrong order.The above stack is from node 16. Node 18 produces a shorter but similarly lacking stack:
Additional information
I am aware that
import()and top-level await complicates this, since modules may be effectively loading in parallel (asynchronously behind the scenes). However, it is absolutely essential that this information is made available somehow.If the output ends up being a list of all modules trying to load the offending module then great, as long as this list is in the order the imports were encountered then that should allow debugging this kind of thing.
At the moment when this occurs it's simply impossible to debug. Since
importgets hoisted by the language you can't even addconsole.logstatements around the place to trace what's happening like you can withrequire. Literally the only option to debug this is to comment out all the imports and re-enable one-by-one (recursively) until you locate the problem. And in practice this inevitably breaks something else, so it's completely unworkable.