Skip to content

fix(dev): use Vite --strictPort so the dev launcher can't drift ports - #2

Open
janpio wants to merge 1 commit into
mainfrom
claude/dev-launcher-strict-port
Open

janpio wants to merge 1 commit into
mainfrom
claude/dev-launcher-strict-port

Conversation

@janpio

@janpio janpio commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes a dev-launcher footgun: when the client port is already in use, npm run dev sends you to the wrong port and auto-opens a stale/incorrect page instead of failing clearly.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Changes Made

The dev launcher (client/bin/start.js) spawns the client as vite --port <CLIENT_PORT>. Without --strictPort, Vite silently falls back to the next free port when CLIENT_PORT is taken (e.g. a leftover instance), but the launcher still builds the "🚀 up and running at" URL — and auto-opens the browser — from the originally requested CLIENT_PORT. Result: you land on the wrong (often stale) port while the real client listens elsewhere, and the proxy's DNS-rebinding origin allow-list (pinned to http://localhost:${CLIENT_PORT}) no longer matches either — a confusing goose chase.

  • Pass --strictPort to Vite so it fails fast instead of drifting; the launcher's advertised URL is then always correct, or startup fails loudly.
  • Cancel the deferred announce/open timer if the client process exits first, so we never advertise or open a URL for a client that isn't actually listening on that port.
  • Print a clear hint (free the port, or set a different CLIENT_PORT) when the client exits unexpectedly.

Related Issues

Testing

  • Tested in UI mode
  • Tested in CLI mode
  • Tested with STDIO transport
  • Tested with SSE transport
  • Tested with Streamable HTTP transport
  • Added/updated automated tests
  • Manual testing performed

Test Results and/or Instructions

To reproduce the original bug: occupy the client port, then start dev — the browser opens the requested port (wrong/stale instance) even though Vite bound a different one.

To verify the fix:

  1. Occupy the port, e.g. python3 -m http.server 6274 (or leave a prior npm run dev running).
  2. From the repo root, run npm run dev.
  3. Before: Vite quietly moves to 6275 and the launcher opens localhost:6274.
    After: Vite exits immediately with a port-in-use error and the launcher prints a hint instead of opening a misleading URL. Freeing the port (or CLIENT_PORT=6280 npm run dev) starts cleanly on the announced port.

npm run prettier-check and client lint both pass. No behavior change on the happy path (port free).

Checklist

  • Code follows the style guidelines (ran npm run prettier-fix)
  • Self-review completed
  • Code is commented where necessary
  • Documentation updated (README, comments, etc.) — code comments only; no README change needed

Breaking Changes

None. When the port is free (the normal case) behavior is unchanged. The only behavioral change is that a port conflict now fails loudly instead of silently switching ports.

Additional Context

Separate from the "apply auth to all requests" work in PR #1 — this is an independent dev-experience fix and touches only client/bin/start.js.

🤖 Generated with Claude Code


Generated by Claude Code

The dev launcher (`client/bin/start.js`) spawns the client as
`vite --port <CLIENT_PORT>`. Without `--strictPort`, Vite silently falls back
to the next free port when CLIENT_PORT is taken (e.g. a stale instance), but
the launcher still builds the "up and running" URL — and auto-opens the
browser — from the originally requested CLIENT_PORT. The user is sent to the
wrong (often stale) port while the real client listens elsewhere, and the
proxy's DNS-rebinding origin allow-list (pinned to
http://localhost:${CLIENT_PORT}) no longer matches either.

Fix:
- Pass `--strictPort` to Vite so it fails fast instead of drifting; the
  launcher's URL is then always correct or startup fails loudly.
- Cancel the deferred announce/open timer if the client process exits first,
  so we never advertise or open a URL for a client that isn't listening.
- Print a clear hint (free the port or set CLIENT_PORT) when the client exits
  unexpectedly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012FAFCf8AzpqyNF1oKZNGzh
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