Skip to content

fix(cli): clearer error when importing .node addon via ESM#34361

Merged
bartlomieju merged 2 commits into
mainfrom
fix/clearer-error-esm-import-node-addon
May 26, 2026
Merged

fix(cli): clearer error when importing .node addon via ESM#34361
bartlomieju merged 2 commits into
mainfrom
fix/clearer-error-esm-import-node-addon

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

Importing a native .node addon through an ESM import statement
previously surfaced as SyntaxError: Unexpected character '\xff' because
the binary file was handed to V8 as JavaScript. Native addons in Node.js
can only be loaded through require(), so detect the .node extension
at the start of load_inner and return a TypeError that points users
at createRequire() from node:module. The legitimate CJS paths
(import "npm:some-pkg" where the package internally requires a
.node file, and explicit createRequire() + require("./addon.node")
in user code) are unaffected.

Fixes #17246

Importing a native `.node` addon through an ESM `import` statement
previously surfaced as `SyntaxError: Unexpected character '\xff'`
because the binary file was handed to V8 as JavaScript. Native addons
in Node.js can only be loaded through `require()`, so detect the
`.node` extension in the module loader and return a TypeError that
points users at `createRequire()` from `node:module`.

Fixes #17246

@fibibot fibibot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No code issue found. The early .node guard in load_inner() runs after resolution and before load_code_source(), so ESM imports get the clearer TypeError while CommonJS require() continues through Module._extensions[".node"]; the spec locks the node_modules subpath case. Holding approval until CI is green.

@fibibot fibibot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI found a real lint failure on this revision, so this needs one small Rust cleanup before approval.

  1. JsErrorBox::type_error(...).into() in cli/module_loader.rs trips clippy::useless_conversion because the expression is already a JsErrorBox. Remove the .into() and return the JsErrorBox directly from Err(...).

@fibibot fibibot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new head removes the .into() that failed clippy, so the prior lint blocker is gone. The .node guard still runs after resolution and before load_code_source(), which gives ESM imports the typed error without touching CommonJS Module._extensions[".node"]; the node_modules spec covers that path. Holding approval until CI is green.

@fibibot fibibot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is green now, promoting prior review to APPROVE.

@bartlomieju
bartlomieju merged commit 598f39d into main May 26, 2026
136 checks passed
@bartlomieju
bartlomieju deleted the fix/clearer-error-esm-import-node-addon branch May 26, 2026 08:24
littledivy pushed a commit to crowlKats/deno that referenced this pull request Jun 10, 2026
…34361)

Importing a native `.node` addon through an ESM `import` statement
previously surfaced as `SyntaxError: Unexpected character '\xff'`
because the binary file was handed to V8 as JavaScript. Native addons in Node.js
can only be loaded through `require()`, so detect the `.node` extension
at the start of `load_inner` and return a `TypeError` that points users
at `createRequire()` from `node:module`. The legitimate CJS paths
(`import "npm:some-pkg"` where the package internally `require`s a
`.node` file, and explicit `createRequire()` + `require("./addon.node")`
in user code) are unaffected.

Fixes denoland#17246
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Loading native Node module fails with "stream did not contain valid UTF-8"

2 participants