You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every api docker image built from current main crashes at boot. The bundled app.js dies during module evaluation, before Nest starts:
file:///app/dist/app.js:226145
globalThis["__dirname"] = __banner_node_path.dirname(__filename2);
^
TypeError: Cannot assign to read only property '__dirname' of object '#<Object>'
The published ghcr.io/…/open-data-capture-api:2.1.6 image is not affected (verified: it boots to the point of querying mongo). The next release built from main as it stands will ship a container that cannot start.
libnest's build banner (line 1 of dist/app.js, present in 8.3.1 and 8.4.0, src/meta/build.ts:66) defines globalThis.__dirname / __filename with writable: false.
@prisma/client@6.19.3's ESM runtime (runtime/library.mjs) opens with its own banner that assignsglobalThis['__dirname'] = …. When the bundle inlines that runtime, the strict-mode assignment hits the non-writable property and throws.
Why it appears now
Dependency pins are unchanged — v2.1.6 and today's main both lock libnest 8.3.1 and prisma 6.19.3, and the 2.1.6 bundle contains zero__banner_node_path markers while a build of 38fa109 contains the inlined .mjs runtime. Something in the v2.1.6..38fa109 window (predominantly the mailer split, #1439) changed the import graph so esbuild now resolves @prisma/client through its import condition and pulls runtime/library.mjs into the bundle. The exact import site was not bisected; it also does not matter for the fix — any future graph change could re-trigger it, so the banner must tolerate the assignment.
Crash is Node-version-independent within the image's range (24.18.0, 24.19.0; node:lts-krypton currently floats to 24.19.0).
Rebuilding with only the banner flipped to writable: true boots and runs the full setup + default instrument-repo import (24/24 instruments) against a mongo replica set.
Add a release-blocking check that the built api image actually boots — this failure is invisible to lint, unit tests, and the e2e suite (which runs the never-bundled dev server), and was only caught by running the container.
Summary
Every api docker image built from current
maincrashes at boot. The bundledapp.jsdies during module evaluation, before Nest starts:The published
ghcr.io/…/open-data-capture-api:2.1.6image is not affected (verified: it boots to the point of querying mongo). The next release built frommainas it stands will ship a container that cannot start.Root cause
Two banners fight over
globalThis.__dirname. Upstream issue with full analysis and a verified fix: DouglasNeuroInformatics/libnest#77.dist/app.js, present in 8.3.1 and 8.4.0,src/meta/build.ts:66) definesglobalThis.__dirname/__filenamewithwritable: false.@prisma/client@6.19.3's ESM runtime (runtime/library.mjs) opens with its own banner that assignsglobalThis['__dirname'] = …. When the bundle inlines that runtime, the strict-mode assignment hits the non-writable property and throws.Why it appears now
Dependency pins are unchanged —
v2.1.6and today'smainboth lock libnest8.3.1and prisma6.19.3, and the 2.1.6 bundle contains zero__banner_node_pathmarkers while a build of38fa109contains the inlined.mjsruntime. Something in thev2.1.6..38fa109window (predominantly the mailer split, #1439) changed the import graph so esbuild now resolves@prisma/clientthrough itsimportcondition and pullsruntime/library.mjsinto the bundle. The exact import site was not bisected; it also does not matter for the fix — any future graph change could re-trigger it, so the banner must tolerate the assignment.Attribution evidence
38fa109(no open-PR code): crashes identically. PR fix(instrument-bundler): keep the esbuild switch alive through tree shaking #1482 explicitly exonerated — noted in the review posted on that PR.node:lts-kryptoncurrently floats to 24.19.0).writable: trueboots and runs the full setup + default instrument-repo import (24/24 instruments) against a mongo replica set.Path to green
writable: true, verified), release, bump here (@douglasneuroinformatics/*is inminimumReleaseAgeExclude, so the bump can land immediately).Repro