Skip to content
Turtle

Trace Warnings with Node

Javascript, Node1 min read

When upgrading to Node 14, I ran into this issue where running the test suite would throw a set of warnings like so:

1(node:79706) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency
2(Use `node --trace-warnings ...` to show where the warning was created)
3(node:79706) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
4(node:79706) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
5(node:79706) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency

One way of finding out what packages were throwing these warnings was by running the same command but with the --trace-warnings option:

1npx cross-env NODE_OPTIONS="--trace-warnings" yarn test

This helped in pinpointing which packages needed to be updated!

Bonus

Here is a contrived example of two classes depending on each other:

1// a.js
2const B = require('./b');
3
4class A {
5 constructor(name) {
6 this.name = name;
7 this.b = new B();
8 this.b.log(name);
9 }
10}
11
12const a = new A('cat')
13
14module.exports = A;
15
16// b.js
17const A = require('./a');
18
19class B {
20 constructor() {
21 this.a = A;
22 console.log(this.a)
23 }
24
25 log(stuff) {
26 console.log(stuff)
27 }
28}
29
30module.exports = B;
31
32// package.json
33 "scripts": {
34 "build": "node a.js"
35 },

Now building our files gives us this warning:

1$ yarn build
2
3(node:18952) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency
4(Use `node --trace-warnings ...` to show where the warning was created)

Now using --trace-warnings we can see where this issue is happening:

1$ npx cross-env NODE_OPTIONS="--trace-warnings" yarn build
2
3(node:18978) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency
4 at emitCircularRequireWarning (node:internal/modules/cjs/loader:698:11)
5 at Object.get (node:internal/modules/cjs/loader:712:5)
6 at formatValue (node:internal/util/inspect:746:30)
7 at inspect (node:internal/util/inspect:330:10)
8 at formatWithOptionsInternal (node:internal/util/inspect:1998:40)
9 at formatWithOptions (node:internal/util/inspect:1880:10)
10 at console.value (node:internal/console/constructor:327:14)
11 at console.log (node:internal/console/constructor:363:61)
12 at new B (/Users/ygaberman/programs/test/b.js:6:17)
13 at new A (/Users/ygaberman/programs/test/a.js:7:18)

The last two lines show us where the dependency is. This is quite useful for chasing down any circular dependencies!


Can we fix it? Yes.