Skip to content

[vite-plugin] Route DevTools WebSocket upgrades explicitly - #16519

Merged
petebacondarwin merged 2 commits into
mainfrom
codex/vite-devtools-websocket-route
Oct 27, 2026
Merged

petebacondarwin merged 2 commits into
mainfrom
codex/vite-devtools-websocket-route

Conversation

@petebacondarwin

@petebacondarwin petebacondarwin commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #15654. Supersedes #16516.

Leave WebSocket upgrades at /__devtools/__ws to Vite DevTools before dispatching to the Worker. Matching URL.pathname also handles query parameters while keeping nearby paths available to the Worker. Sandbox preview hosts continue forwarding every upgrade, including this path.

Remove the socket ownership heuristic introduced in #15659: the byte-count baseline, prepended listener, competing-owner checks, and deferred teardown. Worker upgrades retain disconnected-socket protection and error cleanup. The exact DevTools WebSocket path is reserved on non-Sandbox hosts even when DevTools is disabled; this deliberately scopes the fix to DevTools rather than attempting to coordinate arbitrary third-party upgrade listeners.

The shared handler covers Vite development and preview servers. Miniflare, Wrangler, and the Vitest plugin need no changes because this concerns routing on Vite's shared Node HTTP server.

Validation:

  • pnpm -w test:ci -F @cloudflare/vite-plugin -- src/__tests__/websockets.spec.ts — 19 tests passed, including DevTools message exchange, query parameters, exact path matching, Sandbox forwarding, and a deterministic pipelined HTTP regression.
  • pnpm --filter @cloudflare/vite-plugin check:type — passed.
  • pnpm check:lint and pnpm check:format for the changed files — passed.

  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: this fixes Vite DevTools compatibility without adding configuration or a public API.

Devin Review

@changeset-bot

changeset-bot Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0813e91

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 1 package
Name Type
@cloudflare/vite-plugin Patch

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk Oct 27, 2026
@workers-devprod
workers-devprod requested review from a team and cjol and removed request for a team October 27, 2026 14:25
@workers-devprod

workers-devprod commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • ✅ @cloudflare/wrangler
Show detailed file reviewers

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@ask-bonk

ask-bonk Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

I'm Bonk, and I've done a quick review of your PR.

Routes DevTools WebSocket upgrades explicitly and removes generic socket ownership detection.

  1. P1: Posted 1 inline comment: reserved DevTools paths leave sockets open when no DevTools handler is installed.

github run

@clanky-the-clanker

clanky-the-clanker Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

💬 Approved with comments — The explicit DevTools path check is correct, and the tests cover it well. Two INFO notes remain: the deliberate narrowing to the DevTools path, and the hard-coded path.

Findings: 2 info

The decision is advisory: this comment never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #16519.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## INFO (2)

### [Code Quality] Removing the socket-ownership heuristic means `upgrade` listeners other than DevTools on the shared Vite server get their sockets destroyed again when the Worker returns no WebSocket. This is intentional per the PR description; consider mentioning it in the changeset.
- **File:** packages/vite-plugin-cloudflare/src/websockets.ts:82

### [Code Quality] `/__devtools/__ws` is hard-coded and compared against the raw pathname, so a Vite `base` prefix would not match. Consider a named constant, and confirm DevTools never prefixes this path.
- **File:** packages/vite-plugin-cloudflare/src/websockets.ts:60

📋 Code Quality: 💬 2 info

The DevTools path is now routed correctly. Two INFO notes: the narrower scope compared with the removed socket-ownership heuristic, and the hard-coded path.

Recommendation: 💬 Optional Nits

  • [INFO] Removing the socket-ownership heuristic means upgrade listeners other than DevTools on the shared Vite server get their sockets destroyed again when the Worker returns no WebSocket. This is intentional per the PR description; consider mentioning it in the changeset. (packages/vite-plugin-cloudflare/src/websockets.ts:82)
  • [INFO] /__devtools/__ws is hard-coded and compared against the raw pathname, so a Vite base prefix would not match. Consider a named constant, and confirm DevTools never prefixes this path. (packages/vite-plugin-cloudflare/src/websockets.ts:60)
View full review
  • Narrower scope than the old heuristic (packages/vite-plugin-cloudflare/src/websockets.ts:81-84, :115). The !workerWebSocket branch and the catch block now call socket.destroy() unconditionally. Suppose another upgrade listener on Vite's shared HTTP server answers a path the Worker does not handle, for example another plugin's or framework's socket. That socket will be destroyed again once dispatchFetch returns. The PR description says this is deliberate, so it is not a blocker. A sentence in the changeset would help users who hit the same symptom on another path to recognise the cause.

  • Hard-coded path (packages/vite-plugin-cloudflare/src/websockets.ts:60). The code compares url.pathname === "/__devtools/__ws" against the raw pathname. If Vite DevTools ever builds its socket URL under a configured base, or uses a variant such as a trailing slash, that upgrade would still go to the Worker. Consider a named constant, and confirm that DevTools never prefixes this path.

The tests cover DevTools message exchange, query strings, exact-path matching, Sandbox forwarding and the pipelined-HTTP socket.destroyed guard. They are adequate for this change.


✅ All other checks passed

🔒 Security: ✅ LGTM

No security issues found. Sandbox preview hosts still forward every upgrade, and parsing the URL with URL.pathname keeps the match exact.


📖 AGENTS.md: ✅ LGTM

No AGENTS.md guidance needs updating.


⚡ Performance: ✅ LGTM

No performance issues. The change removes per-socket byte-count tracking and the extra listeners, which simplifies the upgrade path.


📝 Documentation: ✅ LGTM

The changeset is accurate for this change.


Reviewed commit: 0813e91c

@pkg-pr-new

pkg-pr-new Bot commented Oct 27, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@16519

@cloudflare/build-output-utils

npm i https://pkg.pr.new/@cloudflare/build-output-utils@16519

@cloudflare/codemods

npm i https://pkg.pr.new/@cloudflare/codemods@16519

@cloudflare/config

npm i https://pkg.pr.new/@cloudflare/config@16519

@cloudflare/containers-shared

npm i https://pkg.pr.new/@cloudflare/containers-shared@16519

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@16519

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@16519

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@16519

miniflare

npm i https://pkg.pr.new/miniflare@16519

@cloudflare/pages-functions

npm i https://pkg.pr.new/@cloudflare/pages-functions@16519

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@16519

@cloudflare/runtime-types

npm i https://pkg.pr.new/@cloudflare/runtime-types@16519

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@16519

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@16519

@cloudflare/vitest-plugin

npm i https://pkg.pr.new/@cloudflare/vitest-plugin@16519

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@16519

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@16519

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@16519

wrangler

npm i https://pkg.pr.new/wrangler@16519

commit: 0813e91

@petebacondarwin
petebacondarwin requested review from dario-piotrowicz and removed request for cjol October 27, 2026 14:40

@workers-devprod workers-devprod left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codeowners reviews satisfied

@github-project-automation github-project-automation Bot moved this from Untriaged to Approved in workers-sdk Oct 27, 2026
@petebacondarwin
petebacondarwin merged commit cda7856 into main Oct 27, 2026
88 of 89 checks passed
@petebacondarwin
petebacondarwin deleted the codex/vite-devtools-websocket-route branch October 27, 2026 14:44
@github-project-automation github-project-automation Bot moved this from Approved to Done in workers-sdk Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

vite-plugin-cloudflare: dev server destroys WebSockets that don't announce a "vite" subprotocol

3 participants