RedirectMessage rethrown before headersSent check crashes Vite dev middleware (router 2.0-beta.32)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 22.1k
- Forks
- 1.4k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 52
Description
Summary
In @qwik.dev/router@2.0.0-beta.32, the node middleware rethrows RedirectMessage (an AbortMessage subclass) before checking headersSent. RedirectMessage has no .message/.stack, so when it propagates to Vite's viteErrorMiddleware, stripVTControlCharacters(undefined) crashes with TypeError [ERR_INVALID_ARG_TYPE].
Repro
Any throw redirect(302, '/foo') in a routeAction$ or onRequest$ during vite --mode ssr. Example: a successful POST to /auth/login/ that redirects on success.
Expected
Qwik already sent the 302 response (stream closed) — the middleware should return cleanly, not forward the RedirectMessage to next(err).
Actual
RedirectMessage {}
[vite] Internal server error: undefined
TypeError [ERR_INVALID_ARG_TYPE]: The "str" argument must be of type string. Received undefined
at stripVTControlCharacters (node:internal/util/inspect:2765:3)
at prepareError (vite/dist/node/chunks/config.js:9475:12)
at logError (vite/dist/node/chunks/config.js:9504:8)
at viteErrorMiddleware (vite/dist/node/chunks/config.js:9509:3)
...
at router (@qwik.dev/router/lib/middleware/node/index.mjs:162:7)
Root cause
@qwik.dev/router/lib/middleware/node/index.mjs around line 142:
const handled = await requestHandler(serverRequestEv, opts);
if (handled) {
const err = await handled.completion;
if (err) {
throw err; // fires for RedirectMessage
}
if (handled.requestEv.headersSent) {
return; // never reached
}
}
runOnce() (in request-handler/index.mjs around line 1554) already does await stream.close() for RedirectMessage before returning it, so the response is complete — the rethrow is spurious.
Suggested fix
Check headersSent first, or short-circuit on RedirectMessage/AbortMessage:
if (handled) {
const err = await handled.completion;
if (handled.requestEv.headersSent) return;
if (err) throw err;
}
Environment
- `@qwik.dev/router` 2.0.0-beta.32
- `@qwik.dev/core` 2.0.0-beta.32
- Vite 7.3.1
- Node 22 LTS
- Platform: macOS (darwin 25.4.0)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in @qwik.dev/router/lib/middleware/node/index.mjs around line 142, then read runOnce() in request-handler/index.mjs around line 1554 to understand when the stream closes for RedirectMessage. Verify the middleware handles completed responses before forwarding errors, and reproduce the redirect scenario under Vite SSR to confirm no error reaches viteErrorMiddleware.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, vite
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 64/100