Skip to content

Keep the Vite plugin context methods when the client environment generates the public env manifest - #199

Merged
garronej merged 1 commit into
mainfrom
fix/bootstrap-env-client-context-prototype
Oct 4, 2026
Merged

garronej merged 1 commit into
mainfrom
fix/bootstrap-env-client-context-prototype

Conversation

@steelanterns

@steelanterns steelanterns commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Symptom

In vite dev with the TanStack Start adapter (10.2.15), server rendering intermittently fails with:

TypeError: context.addWatchFile is not a function
    at discover (oidc-spa/esm/vite-plugin/handleTanstackStartBootstrapEnv.mjs)
    at scan (...)
    at Object.load (...)
    at LoadPluginContext.load (vite/...)
    at async DevEnvironment.warmupRequest (vite/...)

Cause

When the client environment is the one generating virtual:oidc-spa/tanstack-start-public-env during serve, load swaps the resolver with:

context = { ...context, resolve: resolveFromServerEnvironment };

Vite's PluginContext exposes addWatchFile (and its other methods) on the class prototype, so the spread only copies own properties and addWatchFile is lost. scan() then throws on its first discover() call.

It is intermittent because scanPromise is usually created first by the server environment and reused. Any source change resets it (onSourceChange), and after the full reload it is a race: when the client environment loads the virtual module first (e.g. through a warmup request), the dev server breaks.

Fix

Pass scan() exactly what it needs (resolve from the server environment, addWatchFile delegated to the real plugin context) instead of spreading the context.

Test

The existing "uses the server resolver when loaded by the client" case passes a plain object whose addWatchFile is an own property, so the spread kept it. The new case uses a class instance with the methods on the prototype, like Vite's context. It fails with the error above before the fix and passes after.

npx tsx --test scripts/tests/tanstack-start-bootstrap-env.test.ts: 26/26. (These tests are not run by CI, which only checks format and build; both pass.)

Also checked in a real TanStack Start app (Vite 8.1.3): requesting /@id/__x00__virtual:oidc-spa/tanstack-start-public-env before any SSR reproduces the error on 10.2.15, and no longer does with this change, including after a source change.

Only affects dev (command === "serve"); builds are unaffected. Not needed on v11, which no longer swaps the resolver.

Follow-up to #196.

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility when preparing client environments, including contexts that provide methods through their prototypes.
    • Corrected handling of client environment metadata and file tracking, helping ensure generated builds include the expected environment information and watch the relevant files.
    • Confirmed the server shuts down cleanly after processing this setup.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: bd2c7e8f-9d87-4f32-84d2-a74eb353e3fb

📥 Commits

Reviewing files that changed from the base of the PR and between a80d121 and 25bc01a.

📒 Files selected for processing (2)
  • scripts/tests/tanstack-start-bootstrap-env.test.ts
  • src/vite-plugin/handleTanstackStartBootstrapEnv.ts

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

The client-serving load hook now delegates addWatchFile explicitly when it substitutes the server resolver. A test checks this behavior with a plugin context whose methods are on its prototype.

Changes

Client context handling

Layer / File(s) Summary
Client load hook and test
src/vite-plugin/handleTanstackStartBootstrapEnv.ts, scripts/tests/tanstack-start-bootstrap-env.test.ts
The client load hook delegates addWatchFile explicitly instead of spreading the plugin context. A class-based context test checks the generated manifest, watched files, and server shutdown.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: garronej

Merge Risk: ⚪ Minimal · up to 25bc0

The change preserves watch-file handling for prototype-based contexts while retaining client manifest generation. No concrete merge-blocking risk remains in the reviewed change.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: preserving Vite plugin context methods when the client environment generates the public environment manifest.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@garronej

garronej commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

Thanks a lot @steelanterns !

@garronej
garronej merged commit 4eebf2f into main Oct 4, 2026
6 checks passed
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