Repository navigation
fix(build): keep node:fs out of the client chunk graph (Turbopack /login + /dashboard) - #13568
jonlwheat2-gif wants to merge 1 commit into
Conversation
…gin + /dashboard)
Turbopack (the Next 16 default bundler) panicked while writing the page
endpoints for /login and /(dashboard)/dashboard:
FATAL: An unexpected Turbopack error occurred.
Failed to write app endpoint /login/page
Caused by:
- the chunking context (unknown) does not support external modules
(request: node:fs)
Root cause is a single import chain that drags a module with top-level Node
builtins into a CLIENT component's bundle:
src/app/login/page.tsx (and src/app/(dashboard)/layout.tsx)
-> src/shared/components/index.tsx (barrel)
-> src/shared/components/ModelSelectModal.tsx (client component)
-> src/shared/constants/models.ts
-> @omniroute/open-sse/config/providerModels.ts
-> @omniroute/open-sse/config/providerRegistry.ts
-> @omniroute/open-sse/config/providers/index.ts
-> .../providers/registry/codebuddy-cn/index.ts
-> src/lib/oauth/constants/oauth.ts
-> @omniroute/open-sse/utils/cursorAgentCliVersion.ts
(top-level node:fs / node:os / node:path)
fs/path/os/child_process are listed in `serverExternalPackages` in
next.config.mjs, so Turbopack externalises them — and the browser chunking
context cannot emit an external reference, hence the panic. This is NOT cache
corruption: purging the 1.1 GB `.build/next/dev/cache/turbopack` did not help,
and the same panic predates the auth work.
Fix: split the pinned build id into a client-safe module with no Node builtins.
- NEW open-sse/utils/cursorAgentCliVersion.constants.ts
holds only CURSOR_AGENT_CLI_VERSION (+ a header comment documenting the
chain above), so it is safe to import from browser-bundleable code.
- open-sse/utils/cursorAgentCliVersion.ts
imports the constant from .constants.ts and re-exports it, so the
module's public API is unchanged; its fs/os/path machinery is untouched.
- src/lib/oauth/constants/oauth.ts
imports CURSOR_AGENT_CLI_VERSION from the .constants.ts module instead
of the fs-bearing one.
All Node builtins had to leave the module's top level, not just fs — node:os
and node:path would have panicked next.
Verified:
- /login -> 200 (was 500); /dashboard -> 307/308 -> /login (normal auth redirect)
- /api/monitoring/health -> {"status":"healthy","setupComplete":true}
- zero new next-panic-*.log files
- npx tsc --pretty false -p tsconfig.typecheck-core.json -> clean
- tests/unit/cursor-agent-cli-version.test.ts + tests/unit/cursor-login-pkce.test.ts -> 26/26
Escape hatch (workaround, not a fix): OMNIROUTE_USE_TURBOPACK=0 npm run dev
forces webpack, which tolerates the node:fs reference.
|
CI note — the failing checks are pre-existing, not from this PR. Every failing job here fails identically on Failing everywhere:
Two pinned from the logs:
The base commit |
|
Thanks for tracking this down — the root cause you found (oauth.ts pulling node:fs via Triage note: this is the review recommendation — the close itself happens only after the maintainer's per-PR sign-off (and, where a superseding PR is named, after it has landed). Nothing is being closed by this comment. |
|
Thanks for the fix! The |
Summary
Turbopack (the Next 16 default bundler) was panicking on
npm run devwhile writing the page endpoints for/loginand/(dashboard)/dashboard, so both routes returned 500:This PR fixes the root cause. It is a build/bundling bug, unrelated to #13377.
Root cause
A client component drags a module with top-level Node builtins into the browser chunk graph. There is exactly one chain feeding both failing pages:
fs/path/os/child_processare listed inserverExternalPackages(next.config.mjs), so Turbopack externalises them — and the browser chunking context cannot emit an external reference, hence the panic.What it is NOT
.build/next/dev/cache/turbopack(the remedy the repo's ownscripts/dev/run-next.mjscomment recommends for this error class, fix(startup): Turbopack cache mmap failure surfaces as "Module not found" (os error 1455) #6289) did not help — so thenode:fsreference is real.Fix
Split the pinned build id into a client-safe module with no Node builtins:
open-sse/utils/cursorAgentCliVersion.constants.ts(new)CURSOR_AGENT_CLI_VERSION(+ a header comment documenting the chain above). No Node builtins.open-sse/utils/cursorAgentCliVersion.ts.constants.tsand re-exports it, so the module's public API is unchanged. Itsfs/os/pathmachinery is untouched.src/lib/oauth/constants/oauth.tsCURSOR_AGENT_CLI_VERSIONfrom the.constants.tsmodule instead of the fs-bearing one.Verification
/login→ 200 (was 500)/dashboard→ 307/308 →/login(normal auth redirect)/api/monitoring/health→{"status":"healthy","setupComplete":true}next-panic-*.logfilesnpx tsc --pretty false -p tsconfig.typecheck-core.json→ cleantests/unit/cursor-agent-cli-version.test.ts+tests/unit/cursor-login-pkce.test.ts→ 26/26Escape hatch
OMNIROUTE_USE_TURBOPACK=0 npm run devforces webpack, which tolerates thenode:fsreference and lets the pages compile — but it is a workaround, not a fix.