Which component is affected?
Qwik Optimizer (rust)
Describe the bug
The optimizer's transform_props_destructuring pass treats any arrow
function with a single destructured parameter and a return statement as a
Qwik inline component, regardless of whether the function actually is one.
The pass renames the parameter to _rawProps and rewrites identifier
reads of the destructured names to _rawProps.<name> — but it does not
rewrite the LHS of assignments.
When the function body reassigns the destructured binding (a common pattern
in plain helpers that default an optional argument, e.g.
if (!ogImage) ogImage = …), the rewritten code ends up writing to a
now-undeclared identifier.
User-visible failure modes (all empirically observed, see Additional
Information):
- Dev SSR (
vite --mode ssr): throws ReferenceError: <name> is not defined inside the SSR render path. The error is swallowed by Qwik's
component SSR pipeline and the request hangs forever with no log output.
- Production (
pnpm build + any SSR adapter or vite preview): ships
the same broken code. Depending on the RHS shape and downstream
simplification, either the broken assignment is preserved (template
literal RHS → 500 with the same ReferenceError at runtime) or the
entire conditional is eliminated as dead code (string literal RHS →
silent miscompilation: the default value is never applied).
I intend to submit a PR for this issue. Candidate fix (refusing the
transform when the body reassigns a destructured binding) is on the branch
fix/props-destructuring-reassign-bug against build/v2 — see Additional
Information for the change summary.
Reproduction
https://github.com/46ki75/qwik-v2-optimizer-destructure-reassign-bug
Steps to reproduce
pnpm install
pnpm dev # vite --mode ssr ; serves http://localhost:5173/
curl --max-time 15 http://localhost:5173/
Expected (broken) result: curl exits with timeout (exit code 28). Vite
logs no error.
To see the actual error rather than a hang, switch the invocation in
src/routes/index.tsx to eager (module top-level) form:
import { buildHead } from "~/utils/head";
const _eager = buildHead({});
void _eager;
curl http://localhost:5173/ then returns a 500 with:
"message":"ogImage is not defined"
"stack":" at buildHead (src/utils/head.ts:N:M)
at eval (src/routes/index.tsx:N:M)
at async ESModulesEvaluator.runInlinedModule (vite/.../module-runner.js)
…"
To inspect the Vite-transformed output directly (post-optimizer SSR
module the runtime actually executes):
curl http://localhost:5173/src/utils/head.ts?import
To verify production is also affected:
pnpm build
# Then grep dist/build/q-*.js for the chunk containing "hang repro";
# the body is `const r = e => (e.ogImage || (ogImage = "fallback-image-url"), …)`
# — a write to an undeclared `ogImage` that throws in strict mode at runtime.
System Info
System:
OS: Linux 6.6 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
CPU: (16) x64 Intel(R) Core(TM) Ultra 7 255H
Memory: 6.53 GB / 15.31 GB
Container: Yes
Shell: 5.2.21 - /bin/bash
Binaries:
Node: 24.15.0 - /home/ikuma/.vite-plus/js_runtime/node/24.15.0/bin/node
npm: 11.12.1 - /home/ikuma/.vite-plus/js_runtime/node/24.15.0/bin/npm
pnpm: 10.33.0 - /home/ikuma/.volta/bin/pnpm
Browsers:
Chrome: 148.0.7778.167
npmPackages:
@qwik.dev/core: 2.0.0-beta.35 => 2.0.0-beta.35
@qwik.dev/router: 2.0.0-beta.35 => 2.0.0-beta.35
typescript: 5.8 => 5.8.3
vite: 7.3.2 => 7.3.2
Additional Information
No response
Which component is affected?
Qwik Optimizer (rust)
Describe the bug
The optimizer's
transform_props_destructuringpass treats any arrowfunction with a single destructured parameter and a
returnstatement as aQwik inline component, regardless of whether the function actually is one.
The pass renames the parameter to
_rawPropsand rewrites identifierreads of the destructured names to
_rawProps.<name>— but it does notrewrite the LHS of assignments.
When the function body reassigns the destructured binding (a common pattern
in plain helpers that default an optional argument, e.g.
if (!ogImage) ogImage = …), the rewritten code ends up writing to anow-undeclared identifier.
User-visible failure modes (all empirically observed, see Additional
Information):
vite --mode ssr): throwsReferenceError: <name> is not definedinside the SSR render path. The error is swallowed by Qwik'scomponent SSR pipeline and the request hangs forever with no log output.
pnpm build+ any SSR adapter orvite preview): shipsthe same broken code. Depending on the RHS shape and downstream
simplification, either the broken assignment is preserved (template
literal RHS → 500 with the same
ReferenceErrorat runtime) or theentire conditional is eliminated as dead code (string literal RHS →
silent miscompilation: the default value is never applied).
I intend to submit a PR for this issue. Candidate fix (refusing the
transform when the body reassigns a destructured binding) is on the branch
fix/props-destructuring-reassign-bugagainstbuild/v2— see AdditionalInformation for the change summary.
Reproduction
https://github.com/46ki75/qwik-v2-optimizer-destructure-reassign-bug
Steps to reproduce
pnpm install pnpm dev # vite --mode ssr ; serves http://localhost:5173/ curl --max-time 15 http://localhost:5173/Expected (broken) result:
curlexits with timeout (exit code 28). Vitelogs no error.
To see the actual error rather than a hang, switch the invocation in
src/routes/index.tsxto eager (module top-level) form:curl http://localhost:5173/then returns a 500 with:To inspect the Vite-transformed output directly (post-optimizer SSR
module the runtime actually executes):
curl http://localhost:5173/src/utils/head.ts?importTo verify production is also affected:
System Info
System: OS: Linux 6.6 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat) CPU: (16) x64 Intel(R) Core(TM) Ultra 7 255H Memory: 6.53 GB / 15.31 GB Container: Yes Shell: 5.2.21 - /bin/bash Binaries: Node: 24.15.0 - /home/ikuma/.vite-plus/js_runtime/node/24.15.0/bin/node npm: 11.12.1 - /home/ikuma/.vite-plus/js_runtime/node/24.15.0/bin/npm pnpm: 10.33.0 - /home/ikuma/.volta/bin/pnpm Browsers: Chrome: 148.0.7778.167 npmPackages: @qwik.dev/core: 2.0.0-beta.35 => 2.0.0-beta.35 @qwik.dev/router: 2.0.0-beta.35 => 2.0.0-beta.35 typescript: 5.8 => 5.8.3 vite: 7.3.2 => 7.3.2Additional Information
No response