Observation, found while reproducing #5391's late-failure repro. Not filed against a specific consumer; not blocking anything currently known — filing so triage can rank it.
What I measured
Reproducing #5391 (injecting a spec dist with no reachable node_modules via OBJECTSTACK_SPEC_DIST, before that issue's fix) surfaced two of the override's declared dependencies unresolvable: zod and pg-connection-string. On this repo's current toolchain (vite@8.2.1 + rolldown@1.2.3, base d8b48f495), the two failed differently through the SAME real apps/consolevite build:
zod — silently kept as an unresolved bare import ... from "zod" in the vendor-objectstack chunk. No warning, no error, transform reports 8613 modules transformed and moves on.pg-connection-string — appears to become its own "chunk" entry in the Rollup/Rolldown output bundle map (type: "chunk", fileName: "pg-connection-string", no extension), but that chunk's file is never actually written to dist/. apps/console/vite.config.ts's emit-eager-closure-report plugin (writeBundle hook) walks the eager closure and calls fs.readFileSync(path.join(outDir, fileName)) for every chunk it finds — including this one — and crashes:
error during build:
Build failed with 1 error:
[plugin emit-eager-closure-report]
Error: ENOENT: no such file or directory, open '.../apps/console/dist/pg-connection-string'
at Object.openSync (node:fs:560:18)
at Object.readFileSync (node:fs:444:35)
at .../vite.config.ts...:519:20 (emitEagerClosureReport's writeBundle)
Confirmed the underlying chunk really is empty/unwritten: find dist -iname "*pg-connection*" returns nothing after the build, even though the bundle map handed to writeBundle names it.
Why it's worth a line
emitEagerClosureReport's own header documents two counter-probes specifically so an under-counting walk fails loudly rather than silently reporting a small number — real care was taken here. This is a gap the same spirit should probably close: the walk assumes every chunk in bundle with type === 'chunk' was actually written to outDir, which is not true for at least one shape of externalized/unresolvable import. The crash IS loud (in that sense it's the "good" failure direction the module's header cares about), but the message names neither the real cause (an unresolvable bare import reaching the eager closure) nor points at emit-eager-closure-report's own assumption — it reads as a generic Node ENOENT, several frames removed from the actual problem.
Scope note
Not reachable via #5391's own path any more once that issue's fix lands (the spec-dist override's own dependencies are now validated before the build ever starts). Still reachable by any other future eager-closure member that ends up genuinely unresolvable for other reasons — e.g. the OBJECTSTACK_CLIENT_DIST sibling hook, or a future advancedChunks group misconfiguration.
Possible shapes (not a recommendation)
- Guard the
fs.readFileSync in emitEagerClosureReport with an existence check, and this.error() with a message naming the missing chunk file and suggesting an unresolved import is the likely cause — turning this from a bare ENOENT into a self-diagnosing failure, matching the two existing counter-probes' spirit. - Or: investigate why Rolldown emits a chunk entry for
pg-connection-string at all rather than folding it into the importing chunk as a plain external — that may point at a advancedChunks.groups test unintentionally matching bare external specifiers.
Related: #5391 (where this was found), #5324 / #5266 (the eager-closure report's own history).
Observation, found while reproducing #5391's late-failure repro. Not filed against a specific consumer; not blocking anything currently known — filing so triage can rank it.
What I measured
Reproducing #5391 (injecting a spec dist with no reachable
node_modulesviaOBJECTSTACK_SPEC_DIST, before that issue's fix) surfaced two of the override's declareddependenciesunresolvable:zodandpg-connection-string. On this repo's current toolchain (vite@8.2.1+rolldown@1.2.3, based8b48f495), the two failed differently through the SAME realapps/consolevite build:zod— silently kept as an unresolved bareimport ... from "zod"in thevendor-objectstackchunk. No warning, no error, transform reports8613 modules transformedand moves on.pg-connection-string— appears to become its own "chunk" entry in the Rollup/Rolldown output bundle map (type: "chunk",fileName: "pg-connection-string", no extension), but that chunk's file is never actually written todist/.apps/console/vite.config.ts'semit-eager-closure-reportplugin (writeBundlehook) walks the eager closure and callsfs.readFileSync(path.join(outDir, fileName))for every chunk it finds — including this one — and crashes:Confirmed the underlying chunk really is empty/unwritten:
find dist -iname "*pg-connection*"returns nothing after the build, even though the bundle map handed towriteBundlenames it.Why it's worth a line
emitEagerClosureReport's own header documents two counter-probes specifically so an under-counting walk fails loudly rather than silently reporting a small number — real care was taken here. This is a gap the same spirit should probably close: the walk assumes every chunk inbundlewithtype === 'chunk'was actually written tooutDir, which is not true for at least one shape of externalized/unresolvable import. The crash IS loud (in that sense it's the "good" failure direction the module's header cares about), but the message names neither the real cause (an unresolvable bare import reaching the eager closure) nor points atemit-eager-closure-report's own assumption — it reads as a generic NodeENOENT, several frames removed from the actual problem.Scope note
Not reachable via #5391's own path any more once that issue's fix lands (the spec-dist override's own
dependenciesare now validated before the build ever starts). Still reachable by any other future eager-closure member that ends up genuinely unresolvable for other reasons — e.g. theOBJECTSTACK_CLIENT_DISTsibling hook, or a futureadvancedChunksgroup misconfiguration.Possible shapes (not a recommendation)
fs.readFileSyncinemitEagerClosureReportwith an existence check, andthis.error()with a message naming the missing chunk file and suggesting an unresolved import is the likely cause — turning this from a bareENOENTinto a self-diagnosing failure, matching the two existing counter-probes' spirit.pg-connection-stringat all rather than folding it into the importing chunk as a plain external — that may point at aadvancedChunks.groupstest unintentionally matching bare external specifiers.Related: #5391 (where this was found), #5324 / #5266 (the eager-closure report's own history).