Skip to content

Vitest double-prefixes node:-only built-ins in resolve.external #10630

Description

@orelbn

Describe the bug

Vitest 4 sets config.resolve.external by spreading node:module.builtinModules and then prefixing every entry with node::

config.resolve.external = [
...builtinModules,
...builtinModules.map(m => `node:${m}`),
]
// by setting `noExternal` to `true`, we make sure that
// Vite will never use its own externalization mechanism

On newer Node versions, builtinModules includes some built-ins only in already-prefixed form, for example:

node:sea
node:sqlite
node:test
node:test/reporters

Related documentation: https://nodejs.org/api/modules.html#built-in-modules

This makes Vitest generate invalid double-prefixed entries:

node:node:sea
node:node:sqlite
node:node:test
node:node:test/reporters

This surfaced downstream with @cloudflare/vite-plugin@1.42.1, which still rejects Vitest startup because resolve.external contains these non-built-in node:node:* entries.

Reproduction

On Node v24.14.1:

import { builtinModules } from "node:module";

console.log(
  builtinModules
    .flatMap((m) => [m, `node:${m}`])
    .filter((m) => m.includes("sea") || m.includes("sqlite") || m.includes("test")),
);

Output includes:

node:sea
node:sqlite
node:test
node:test/reporters
node:node:sea
node:node:sqlite
node:node:test
node:node:test/reporters

Expected behavior

Vitest should not add a second node: prefix when a built-in already starts with node:.

For example:

config.resolve.external = [
  ...builtinModules,
  ...builtinModules.map((m) => (m.startsWith("node:") ? m : `node:${m}`)),
];

System Info

  • Vitest: 4.1.9
  • Node: v24.14.1
  • OS: macOS arm64
  • Package manager: Bun

Additional context

This appears related in spirit to #8925, but this report is specifically about Node’s own node:-only built-ins being double-prefixed.

Filed by GPT-5.5.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions