Describe the bug
When the absolute path of a test file contains a +, browser mode hangs forever at Test Files 0 passed with no error. The browser launches and the orchestrator loads, but no test ever runs until the process is killed.
Root cause: createTestIframe in packages/browser/src/client/orchestrator.ts interpolates the test-file path (iframeId) into the tester iframe URL query without encoding:
const src = `/?sessionId=${getBrowserState().sessionId}&iframeId=${iframeId}`
The tester reads it back with new URL(location.href).searchParams.get('iframeId'). A + in a URL query component is decoded as a space, so the tester's iframeId (…/a b.test.ts) no longer matches the one the orchestrator sends in its prepare/execute events (…/a+b.test.ts). The tester ignores every event, the orchestrator's prepare promise never resolves, and the run hangs.
This hits any project whose path contains a + — e.g. a git worktree named feat+whatever-…. Confirmed on main and v4.1.8.
Reproduction
https://github.com/Pduhard/vitest-browser-hang-plus-path
pnpm install
pnpm exec playwright install chromium
pnpm test
The repo contains a single test file named a+b.test.ts, so its absolute path always contains a + wherever it is cloned.
- Expected: the test in
a+b.test.ts runs and passes.
- Actual: the run hangs forever at
Test Files 0 passed / Tests 0 passed.
- Control: renaming the file to
ab.test.ts (no +) makes it pass in ~1s.
System Info
System:
OS: macOS 26.3
CPU: (10) arm64 Apple M5
Memory: 24.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.22.1
npm: 10.9.4
pnpm: 10.28.0
Browsers:
Chrome: 148.0.7778.215
Safari: 26.3
npmPackages:
@vitest/browser-playwright: 4.1.8 => 4.1.8
playwright: 1.60.0 => 1.60.0
vitest: 4.1.8 => 4.1.8
Used Package Manager
pnpm
Validations
Describe the bug
When the absolute path of a test file contains a
+, browser mode hangs forever atTest Files 0 passedwith no error. The browser launches and the orchestrator loads, but no test ever runs until the process is killed.Root cause:
createTestIframeinpackages/browser/src/client/orchestrator.tsinterpolates the test-file path (iframeId) into the tester iframe URL query without encoding:The tester reads it back with
new URL(location.href).searchParams.get('iframeId'). A+in a URL query component is decoded as a space, so the tester'siframeId(…/a b.test.ts) no longer matches the one the orchestrator sends in itsprepare/executeevents (…/a+b.test.ts). The tester ignores every event, the orchestrator'spreparepromise never resolves, and the run hangs.This hits any project whose path contains a
+— e.g. a git worktree namedfeat+whatever-…. Confirmed onmainandv4.1.8.Reproduction
https://github.com/Pduhard/vitest-browser-hang-plus-path
pnpm install pnpm exec playwright install chromium pnpm testThe repo contains a single test file named
a+b.test.ts, so its absolute path always contains a+wherever it is cloned.a+b.test.tsruns and passes.Test Files 0 passed/Tests 0 passed.ab.test.ts(no+) makes it pass in ~1s.System Info
System: OS: macOS 26.3 CPU: (10) arm64 Apple M5 Memory: 24.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 22.22.1 npm: 10.9.4 pnpm: 10.28.0 Browsers: Chrome: 148.0.7778.215 Safari: 26.3 npmPackages: @vitest/browser-playwright: 4.1.8 => 4.1.8 playwright: 1.60.0 => 1.60.0 vitest: 4.1.8 => 4.1.8Used Package Manager
pnpm
Validations