Skip to content

fix(build): keep node:fs out of the client chunk graph for /dashboard/logs - #13604

Closed
hartmark wants to merge 2 commits into
diegosouzapw:release/v3.8.51from
hartmark:fix/dashboard-logs-cursor-cli-version-client-leak
Closed

hartmark wants to merge 2 commits into
diegosouzapw:release/v3.8.51from
hartmark:fix/dashboard-logs-cursor-cli-version-client-leak

Conversation

@hartmark

Copy link
Copy Markdown
Contributor

Problem

/dashboard/logs panicked live in Turbopack dev mode:

An unexpected Turbopack error occurred.
Failed to write app endpoint /(dashboard)/dashboard/logs/page
Caused by:
- the chunking context (unknown) does not support external modules (request: node:fs)

Root cause

Same underlying issue as #13436 / #13509 / #13568: open-sse/utils/cursorAgentCliVersion.ts imports node:fs/node:os/node:path for local Cursor CLI install detection. Those three PRs already cut several edges reaching it (login page, combo control center, a CLI-tools page). This is a further, previously-undiscovered edge: src/lib/oauth/constants/oauth.ts imports CURSOR_AGENT_CLI_VERSION from the full resolver, and oauth.ts turns out to be reachable from a very large share of the dashboard's client bundles — confirmed via the repo's own client-bundle-no-server-only-10692.test.ts guard: registering the file as server-only and re-running the guard against the un-fixed source reports 250+ offending client entry points, via open-sse/config/providerModels.ts, open-sse/services/usage/supportedProviders.ts, and others.

/dashboard/logs is simply the first of those 250+ pages that Turbopack's lazy dev-mode compilation happened to reach.

Fix

Same pattern as the sibling PRs: the pin string moves to a new import-free cursorAgentCliVersionPin.ts (single source of truth). cursorAgentCliVersion.ts and oauth.ts both import it from there instead of duplicating it inline. cursorAgentCliVersion.ts itself is otherwise unchanged — it still owns the full env → local-install → disk-cache → pin resolution used by real Cursor CLI impersonation call sites.

Also registers open-sse/utils/cursorAgentCliVersion.ts in the existing client-bundle-no-server-only-10692.test.ts guard's SERVER_ONLY list, so this reproduces as a real, fast test failure rather than only a live Turbopack panic, and any future edge reaching it fails CI immediately (independent of whether #13436's broader Node-builtin-detection widening lands).

Testing

  • client-bundle-no-server-only-10692.test.ts: confirmed it fails (250+ offending entries reported) against the un-fixed source with only the SERVER_ONLY registration added, and passes clean with the fix.
  • tests/unit/cursor-agent-cli-version.test.ts (6 tests) and tests/unit/cursor-login-pkce.test.ts (20 tests) — all pass unmodified.
  • tsc -p tsconfig.typecheck-core.json clean.
  • Reproduced the live Turbopack panic on /dashboard/logs before the fix, confirmed clean after.

🤖 Generated with Claude Code

…/logs

Same root cause as diegosouzapw#13436/diegosouzapw#13509/diegosouzapw#13568: open-sse/utils/cursorAgentCliVersion.ts
imports node:fs/node:os/node:path (local Cursor CLI install detection), and
those PRs already cut several edges reaching it. This is a further,
previously-undiscovered edge: src/lib/oauth/constants/oauth.ts imports
CURSOR_AGENT_CLI_VERSION from the full resolver, and oauth.ts turns out to be
reachable from a very large share of the dashboard's client bundles (250+
pages/components in this repo, confirmed by the existing client-bundle guard
test) via open-sse/config/providerModels.ts and
open-sse/services/usage/supportedProviders.ts among others.

Reproduced live: /dashboard/logs panicked with
  "the chunking context (unknown) does not support external modules
   (request: node:fs)"
the first time Turbopack dev-mode compiled that page's client bundle.

Same fix as the sibling PRs: the pin string moves to a new import-free
cursorAgentCliVersionPin.ts (single source of truth); cursorAgentCliVersion.ts
and oauth.ts both import it from there instead of duplicating it inline.
cursorAgentCliVersion.ts itself is otherwise unchanged -- it still owns the
full env -> local-install -> disk-cache -> pin resolution used by real
Cursor CLI impersonation call sites.

Also registers open-sse/utils/cursorAgentCliVersion.ts in the existing
client-bundle-no-server-only-10692.test.ts guard's hardcoded SERVER_ONLY
list, so this reproduces as a real test failure (250+ offending entry
points) rather than only a live Turbopack panic, and any future edge
reaching it fails CI immediately.
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 13, 2026
…nt chunk graph for /dashboard/logs) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 14, 2026
…nt chunk graph for /dashboard/logs) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 14, 2026
…nt chunk graph for /dashboard/logs) into dev/omniroute-dev-combined
@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for the fix — verified locally: the exact ModelSelectModal → models.ts → providerModels → providerRegistry → providers/index → codebuddy-cn → oauth.ts → cursorAgentCliVersion.ts
chain is real on the current tip, and the existing client-bundle-no-server-only-10692 guard
currently misses it (only catches a hardcoded module list). Your fix is clean and the guard
update closes that gap — nice touch citing #13436/#13509/#13568 in the comment, you clearly
checked for overlap. Only ask before merge: could you add a changelog fragment
(changelog.d/fixes/13604-*.md)? Everything else looks ready.

@hartmark

Copy link
Copy Markdown
Contributor Author

Added the changelog fragment — changelog.d/fixes/13604-dashboard-logs-cursor-cli-version-client-leak.md, verified with check:changelog-integrity. Ready to merge from my side.

hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 15, 2026
…nt chunk graph for /dashboard/logs) into dev/omniroute-dev-combined
@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for the fix! The node:fs client-bundle break landed via #13436, which moves the same server-only imports out of the client chunk graph and also widens the client-bundle guard so any Node builtin reaching a client entry fails the test (with resolved-edge caching so the guard stays fast). With that merged this PR no longer applies cleanly and its change is covered. Closing as covered by #13436.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants