Skip to content

fix(client): stop client proxies from resolving primitive coercion over the network - #1815

Merged
dinwwwh merged 2 commits into
1.xfrom
claude/backward-implement-consts-1809-8c7444
Aug 8, 2026
Merged

fix(client): stop client proxies from resolving primitive coercion over the network#1815
dinwwwh merged 2 commits into
1.xfrom
claude/backward-implement-consts-1809-8c7444

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Aug 8, 2026

Copy link
Copy Markdown
Member

Backports RECURSIVE_CLIENT_UNWRAP_KEYS from v2 to the 1.x line. Client proxies no longer treat bind, valueOf, toString, and toJSON as procedure paths, so String(client), template literals, and JSON.stringify(client) resolve normally instead of throwing or issuing spurious RPCs — including the React 19.2 dev-build freeze when a client is passed through props.

Resolves #1809

Fixes

  • createORPCClient and createSafeClient no longer fire network requests or throw on primitive coercion and serialization.
  • createRouterUtils in all query integrations (tanstack-query, react-query, vue-query, solid-query, svelte-query, vue-colada, react-swr) gained the same unwrap keys plus v2's isTypescriptObject guard: JSON.stringify of utils built over a server-side client no longer crashes, and utils.call on server-side clients now returns the underlying client as documented.
  • Unlike v2, then is intentionally not in the unwrap set: v1 keeps supporting procedures named then via preventNativeAwait, so no existing behavior breaks in a patch release.

Testing

  • New coercion/serialization tests for the client, safe client, and every integration's router utils; changed files are at 100% statement/branch/function/line coverage.
  • All 713 unit tests across the touched packages pass; e2e failures observed locally are identical on a clean checkout (environment timing, unrelated).

…er the network

Backport RECURSIVE_CLIENT_UNWRAP_KEYS from v2 so createORPCClient,
createSafeClient, and every createRouterUtils integration resolve
bind/valueOf/toString/toJSON to the underlying value instead of
treating them as procedure paths. Unlike v2, 'then' stays out of the
set because v1 supports procedures named 'then' via preventNativeAwait.

Resolves #1809
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
orpc Ready Ready Preview Aug 8, 2026 2:44am

@dinwwwh

dinwwwh commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

Please review this PR if you have time @jeshuaborges

@pkg-pr-new

pkg-pr-new Bot commented Aug 8, 2026

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@1815

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@1815

@orpc/client

npm i https://pkg.pr.new/@orpc/client@1815

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@1815

@orpc/experimental-durable-iterator

npm i https://pkg.pr.new/@orpc/experimental-durable-iterator@1815

@orpc/hey-api

npm i https://pkg.pr.new/@orpc/hey-api@1815

@orpc/interop

npm i https://pkg.pr.new/@orpc/interop@1815

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@1815

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@1815

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@1815

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@1815

@orpc/otel

npm i https://pkg.pr.new/@orpc/otel@1815

@orpc/experimental-pino

npm i https://pkg.pr.new/@orpc/experimental-pino@1815

@orpc/experimental-publisher

npm i https://pkg.pr.new/@orpc/experimental-publisher@1815

@orpc/experimental-publisher-durable-object

npm i https://pkg.pr.new/@orpc/experimental-publisher-durable-object@1815

@orpc/experimental-ratelimit

npm i https://pkg.pr.new/@orpc/experimental-ratelimit@1815

@orpc/react

npm i https://pkg.pr.new/@orpc/react@1815

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@1815

@orpc/experimental-react-swr

npm i https://pkg.pr.new/@orpc/experimental-react-swr@1815

@orpc/server

npm i https://pkg.pr.new/@orpc/server@1815

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@1815

@orpc/solid-query

npm i https://pkg.pr.new/@orpc/solid-query@1815

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@1815

@orpc/standard-server-aws-lambda

npm i https://pkg.pr.new/@orpc/standard-server-aws-lambda@1815

@orpc/standard-server-fastify

npm i https://pkg.pr.new/@orpc/standard-server-fastify@1815

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@1815

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@1815

@orpc/standard-server-peer

npm i https://pkg.pr.new/@orpc/standard-server-peer@1815

@orpc/svelte-query

npm i https://pkg.pr.new/@orpc/svelte-query@1815

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@1815

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@1815

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@1815

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@1815

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@1815

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@1815

commit: 68c9701

@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — backport of v2's RECURSIVE_CLIENT_UNWRAP_KEYS (bind, valueOf, toString, toJSON) to the 1.x client proxies:

  • packages/client/src/consts.ts — new RECURSIVE_CLIENT_UNWRAP_KEYS set.
  • packages/client/src/client.ts + packages/client/src/client-safe.ts — recursive proxy get now returns Reflect.get(target, key) for unwrap keys instead of recursing into a new sub-client, so primitive coercion / JSON.stringify no longer fire RPCs or throw.
  • Seven query integrations' router-utils.ts (react-query, react-swr, solid-query, svelte-query, tanstack-query, vue-query, vue-colada) — same unwrap guard in outer and inner proxy, plus an isTypescriptObject guard so utils built over a non-object (e.g. undefined) server-side client no longer crash, and utils.call returns the underlying client as documented.
  • Coercion/serialization + non-object-client tests added in every touched package (claimed 100% statement/branch/function/line coverage).

I traced the guard logic against the v2 reference on origin/main and it is faithful, with the one documented divergence that then is intentionally omitted to keep then-named procedures working via preventNativeAwait. The new tests are meaningful — without the fix String(client) demonstrably fires link.call, and they assert not.toBeCalled(). Non-string props, symbol access, and leaf-procedure recursion (existing utils.key.pong tests) all remain intact because isTypescriptObject returns true for functions.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ Minor suggestions only — the docs warning is accurate and well-placed; one small clarification inline.

Reviewed changes — since the prior pullfrog review (75e6c74), one new commit 5802a53e adds a single docs change to apps/content/docs/router.md: a ::: warning note after the basic router example advising against the reserved router keys then, bind, valueOf, toString, toJSON.

The rest of the PR (the RECURSIVE_CLIENT_UNWRAP_KEYS backport across @orpc/client and all query integrations, plus tests) is unchanged from my earlier review, which found no issues.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread apps/content/docs/router.md
@pullfrog

pullfrog Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Run failed. View the logs →

Pullfrog  | Rerun failed job ➔View workflow run | via Pullfrog | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit 149c13e into 1.x Aug 8, 2026
6 checks passed
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.

1 participant