Node adapter build fails on unresolved "cloudflare:sockets" import in registry artifact-fetch (0.36.0+)
Description
Since 0.36.0, any site on the Node adapter fails to build because Rollup cannot resolve the cloudflare:sockets specifier in the registry artifact transport:
[vite]: Rollup failed to resolve import "cloudflare:sockets" from
"node_modules/emdash/dist/artifact-fetch-P2JXVwOq.mjs".The runtime behaviour is already correct — createRuntimeRegistryArtifactTransport() in packages/core/src/registry/artifact-fetch.ts wraps the dynamic import in a try/catch and falls back to createNodeRegistryArtifactTransport():
async function createRuntimeRegistryArtifactTransport(): Promise<RegistryArtifactTransport> {
try {
// @ts-ignore - virtual module
const sockets: unknown = await import("cloudflare:sockets");
const connect = objectProperty(sockets, "connect");
if (!isWorkerSocketConnect(connect)) throw new TypeError("Workers socket binding is invalid");
return createWorkersRegistryArtifactTransport(connect);
} catch {
return createNodeRegistryArtifactTransport();
}
}So this is purely a build-time failure: the specifier is a static string literal, so Rollup tries to resolve it during the consumer's Astro build and errors before the guard ever runs. Node-adapter sites cannot build at all past 0.35.0 without a workaround.
This also looks inconsistent with how the rest of core treats Workers built-ins. cloudflare:workers is deliberately kept out of core and routed through a virtual module instead — packages/core/src/astro/integration/virtual-modules.ts emits export { env } from "cloudflare:workers"; only under the Cloudflare adapter, with the comment:
core stays adapter-agnostic, with no direct
cloudflare:workersimport
artifact-fetch.ts is the one place that imports a cloudflare: built-in directly.
Suggested fix
Two options, both inside emdash rather than in every consumer's config:
Externalize the scheme on the non-Cloudflare path.
packages/core/src/astro/integration/vite-config.tsalready maintains a Node-only external list for exactly this class of problem:const NODE_NATIVE_EXTERNALS = ["@libsql/kysely-libsql", "pg"];Modules that contain native Node.js addons or Node-only code. These must be external in SSR to avoid bundling failures on Node. On Cloudflare, the adapter handles its own externalization […]
Adding
/^cloudflare:/there (and tobuild.rollupOptions.external, since the failure is in the Rollup build rather than SSR resolution) would fix every Node-adapter consumer without them knowing this exists.Route it through the existing virtual-module pattern, as
cloudflare:workersalready is, so the specifier is only ever emitted under@astrojs/cloudflare. This is more consistent with the stated adapter-agnostic design of core.
Steps to reproduce
- Create an EmDash site on the Node adapter (
@astrojs/nodeinstandalonemode,output: "server"). - Install
[email protected]or later (reproduced on 0.36.0, 0.37.0 and 0.38.0). - Run
astro build.
The build fails during "Building server entrypoints…". Pinning to [email protected] builds clean — packages/core/src/registry/artifact-fetch.ts does not exist before 0.36.0.
Workaround — externalizing the scheme in the site's own astro.config.mjs builds and runs correctly, with the Node transport selected at runtime as intended:
export default defineConfig({
// …
vite: {
build: {
rollupOptions: {
external: [/^cloudflare:/],
},
},
},
});artifact-fetch.ts was introduced in 0.36.0, which git tag --contains puts at commit e3ad0823 ("feat(registry): hide unapproved listings in EmDash", #2647).
Environment
emdash0.38.0 (also reproduced on 0.36.0 and 0.37.0; 0.35.0 unaffected)astro6.1.3@astrojs/node10.0.4 (mode: "standalone")@astrojs/react5.0.2- Node.js 22.22.2
- pnpm 10.33.0
- Database: SQLite via
better-sqlite312.8.0 - OS: Debian (arm64)
Screenshots
Not applicable — this is a build-time failure, error output below.
Logs / error output
[build] Building server entrypoints...
[ERROR] [vite] ✗ Build failed in 2.62s
[vite]: Rollup failed to resolve import "cloudflare:sockets" from
"/home/pi/emdash-cms/node_modules/.pnpm/[email protected]_.../node_modules/emdash/dist/artifact-fetch-P2JXVwOq.mjs".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
Stack trace:
at viteLog (.../vite/dist/node/chunks/config.js:33635:57)
at onwarn (.../@vitejs/plugin-react/dist/index.js:76:7)
at onRollupLog (.../vite/dist/node/chunks/config.js:33664:63)
at .../rollup/dist/es/shared/node-entry.js:21369:32
at ModuleLoader.handleInvalidResolvedId (.../rollup/dist/es/shared/node-entry.js:22108:26)
ELIFECYCLE Command failed with exit code 1.Source: emdash-cms/emdash