From 9ec72b97d66b10d5cbf3daba0ac48530671715ea Mon Sep 17 00:00:00 2001 From: Kentaro Wakayama Date: Thu, 6 Aug 2026 00:50:21 +0200 Subject: [PATCH] fix(build): embed the declarative evaluator worker entry in compiled binaries workerEntryUrl() resolves the worker through a computed sibling URL, which deno compile's module graph cannot follow, so the module was never embedded. The binary booted fine and only failed the first time hosted declarative config evaluation spawned the worker. The child-worker failure is unhandled, so it took the process down rather than failing that one request: Module not found: file:///tmp/deno-compile-veryfront/src/config/declarative-evaluator-worker-entry.ts The dist/framework-src copy does not satisfy this: it ships renamed to .src as a data asset, not as a module at the path the runner resolves. Latent since dbe5ab190 (#3245), which added both the worker and its computed spawn without the matching include. Surfaced when veryfront-server 20260805195841-cafa104cc127 met production traffic and crashlooped. Adds a guard covering every worker entrypoint under src/, not just this one, since this is the fourth computed-URL worker in DEFAULT_INCLUDES. --- scripts/build/compile-binary.ts | 6 +++ .../build/compile-binary-includes.test.ts | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/scripts/build/compile-binary.ts b/scripts/build/compile-binary.ts index ba57874005..1c930042fa 100644 --- a/scripts/build/compile-binary.ts +++ b/scripts/build/compile-binary.ts @@ -11,6 +11,12 @@ export const DEFAULT_INCLUDES = [ "src/platform/polyfills", "src/proxy/main.ts", "src/security/sandbox/worker-script.ts", + // Spawned through a computed sibling URL in + // src/config/declarative-evaluator-worker-runner.ts, which compile cannot + // trace. Without this the binary boots and only fails when the declarative + // config evaluator first runs, and the unhandled child-worker error takes + // the process down instead of failing the single request. + "src/config/declarative-evaluator-worker-entry.ts", "extensions/ext-auth-jwt/src/index.ts", // Explicit extensions remain inert until selected. Default extensions are // activated by the normal builtin composition when their source is embedded. diff --git a/tests/unit/build/compile-binary-includes.test.ts b/tests/unit/build/compile-binary-includes.test.ts index 0efc744b9b..2f0f9184cf 100644 --- a/tests/unit/build/compile-binary-includes.test.ts +++ b/tests/unit/build/compile-binary-includes.test.ts @@ -110,4 +110,47 @@ describe("compile-binary includes", () => { ); } }); + + it("should include every worker entrypoint under src", async () => { + // Worker entrypoints are reached through a computed sibling URL, e.g. + // `new URL(`./name-worker-entry${extension}`, import.meta.url)`, which + // deno compile's module graph cannot follow. A missing entry compiles and + // boots fine, then throws "Module not found" the first time the worker is + // spawned. The child-worker failure is unhandled, so it takes the whole + // process down rather than degrading that one request. + // + // Regression: src/config/declarative-evaluator-worker-entry.ts was absent, + // which crashlooped veryfront-server in production once traffic reached + // the declarative config evaluator. + const workerEntrypoints: string[] = []; + async function collect(dir: string): Promise { + for await (const entry of Deno.readDir(dir)) { + const path = `${dir}/${entry.name}`; + if (entry.isDirectory) { + await collect(path); + continue; + } + if (!entry.isFile || entry.name.endsWith(".test.ts")) continue; + if (/-worker-entry\.ts$|(?:^|-)worker-script\.ts$/.test(entry.name)) { + workerEntrypoints.push(path); + } + } + } + await collect("src"); + + assertEquals( + workerEntrypoints.length > 0, + true, + "expected to discover at least one worker entrypoint under src", + ); + + const includeFlags = getIncludeFlags(); + for (const entrypoint of workerEntrypoints) { + assertEquals( + includeFlags.some((path) => entrypoint === path || entrypoint.startsWith(`${path}/`)), + true, + `${entrypoint} must be in compile-binary.ts DEFAULT_INCLUDES; deno compile cannot trace the computed worker URL, so the binary crashes when the worker is spawned`, + ); + } + }); });