Skip to content

fix(core): _restProps falls back to plain-object copy for non-props inputs - #8897

Open
blakeley wants to merge 1 commit into
QwikDev:mainfrom
blakeley:fix/core-restprops-plain-object
Open

fix(core): _restProps falls back to plain-object copy for non-props inputs#8897
blakeley wants to merge 1 commit into
QwikDev:mainfrom
blakeley:fix/core-restprops-plain-object

Conversation

@blakeley

@blakeley blakeley commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #8894

Problem

The optimizer emits _restProps for any rest destructure it hoists into a QRL segment, not just component prop destructures. A routeLoader$ such as:

export const useThing = routeLoader$(async () => {
  const { secret, ...rest } = await fetchThing();
  return rest;
});

is compiled to _restProps(await fetchThing(), ["secret"]) (visible in the SSR transform output of the repro below).

But _restProps only knew how to read the _VAR_PROPS / _CONST_PROPS symbols, which exist solely on component props proxies. Given a plain object neither symbol is present, both loops iterate nothing, and the helper returns an empty props proxy. The rest object silently loses every key — no error, no warning, just missing data in the loader payload.

Fix

_restProps now detects a non-props input (both _VAR_PROPS and _CONST_PROPS are undefined) and falls back to native rest-destructure semantics: copy the input's own enumerable keys, minus the omit list, into target and return target itself — a plain object, not a props proxy.

The existing props-proxy path is untouched, so there is no behavior change for component props.

Repro

Minimal reproduction: https://github.com/blakeley/restprops-plain-object-empty

Tests

Added packages/qwik/src/core/shared/utils/prop.unit.ts with four cases, all of which fail on main and pass with the fix:

  • plain object {a:1,b:2,c:3} with omit ["a"]{b:2,c:3}
  • plain object with an empty omit list → every key copied
  • the result for a plain object is a plain object, not a props proxy
  • the provided target is written into and returned

The full packages/qwik/src/core vitest suite is green (2057 passed).

…nputs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@blakeley
blakeley requested a review from a team as a code owner August 1, 2026 00:01
@changeset-bot

changeset-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b68b1bb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@qwik.dev/core Patch
eslint-plugin-qwik Patch
@qwik.dev/react Patch
@qwik.dev/router Patch
create-qwik Patch

Not sure what this means? Click here to learn what changesets are.

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

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.

[🐞] v2: optimizer compiles plain rest destructuring in loaders to core's _restProps, which returns an empty object — silent data loss

1 participant