Skip to content

fix(openapi): give path params precedence in compact input - #2191

Merged
dinwwwh merged 1 commit into
1.xfrom
claude/path-param-collision-security-8c2ac5
Oct 7, 2026
Merged

dinwwwh merged 1 commit into
1.xfrom
claude/path-param-collision-security-8c2ac5

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 7, 2026

Copy link
Copy Markdown
Member

In compact input structure, path params were spread before the query or body, so a colliding key from the client replaced the value the router took from the URL. On 1.15.4, POST /posts/24 with body {"id":"99"} reached the handler as { id: '99' }. Any middleware that authorized against the path param could then hand the handler a different id than the one it checked. Path params now win on collision. This backports #1947 and #1978 from main to 1.x, where latest currently points.

Fixes

  • A body or query field can no longer replace a path param, so authorization and ownership checks see the routed value.
  • On a route with path params, a body that cannot be merged (primitive, array, file) now yields only the path params. Previously the params were dropped and the body became the input. For a raw upload, that let input.name carry the client's Content-Disposition filename on a /{name} route.
  • Routes without path params are unchanged: a non-object body is still the full input.

Compatibility

Round-trips through an oRPC client are unchanged, because the client never sends a key that collides with a path param. The 1.x OpenAPI generator already requires an object input schema containing every path param on compact routes, so bodies that cannot be merged would already have failed validation there.

Docs

The compact input section now says path params take precedence, and that only the path params are used when the body cannot be merged.

Testing

  • vitest run packages/openapi packages/openapi-client: 416 passed.
  • The 6 new codec and end-to-end handler tests fail against the previous codec.
  • eslint and the type-check of the openapi source and touched tests are clean.

In compact input structure, path params were spread before the query or
body, so a colliding key from the client replaced the value the router
took from the URL. Middleware that authorized against the path param
could then hand the handler a different value than the one it checked.

Path params now win on collision. When the body cannot be merged
(primitive, array, Blob, ...), only the path params are used, matching
the OpenAPI generator. Backports #1947 and #1978 from main.
@pullfrog

pullfrog Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

This run was cancelled 🛑

The workflow was cancelled before completion. Please check the link below for details.

Pullfrog  | View workflow run | via Pullfrog | 𝕏

@codecov

codecov Bot commented Oct 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@pkg-pr-new

pkg-pr-new Bot commented Oct 7, 2026

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

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

@orpc/arktype

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

@orpc/client

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

@orpc/contract

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

@orpc/experimental-durable-iterator

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

@orpc/hey-api

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

@orpc/interop

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

@orpc/json-schema

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

@orpc/nest

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

@orpc/openapi

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

@orpc/openapi-client

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

@orpc/otel

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

@orpc/experimental-pino

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

@orpc/experimental-publisher

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

@orpc/experimental-publisher-durable-object

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

@orpc/experimental-ratelimit

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

@orpc/react

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

@orpc/react-query

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

@orpc/experimental-react-swr

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

@orpc/server

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

@orpc/shared

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

@orpc/solid-query

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

@orpc/standard-server

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

@orpc/standard-server-aws-lambda

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

@orpc/standard-server-fastify

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

@orpc/standard-server-fetch

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

@orpc/standard-server-node

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

@orpc/standard-server-peer

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

@orpc/svelte-query

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

@orpc/tanstack-query

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

@orpc/trpc

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

@orpc/valibot

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

@orpc/vue-colada

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

@orpc/vue-query

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

@orpc/zod

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

commit: c17c161

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
orpc 4c223de Oct 07 2026, 10:07 AM

@dinwwwh
dinwwwh merged commit 0754ca6 into 1.x Oct 7, 2026
4 of 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