-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: raw response handling #5276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a raw-response pathway: new Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User Code
participant C as Client API
participant F as serverFnFetcher
participant S as Server handler
U->>C: call serverFn(...)
C->>F: invoke fetcher
F->>S: HTTP request
alt Server returns raw Response
S-->>F: Response (headers include x-tss-raw: "true")
note right of F #DDEBF7: fetcher detects header\nand short-circuits
F-->>C: return raw Response
C-->>U: Response
else Server returns serialized payload
S-->>F: serialized body (JSON)
F->>F: parse & deserialize
F-->>C: structured data
C-->>U: data
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests
Comment |
|
Command | Status | Duration | Result |
---|---|---|---|
nx affected --targets=test:eslint,test:unit,tes... |
❌ Failed | 1m 5s | View ↗ |
nx run-many --target=build --exclude=examples/*... |
❌ Failed | 5s | View ↗ |
☁️ Nx Cloud last updated this comment at 2025-09-28 18:32:04
UTC
More templates
@tanstack/arktype-adapter
@tanstack/directive-functions-plugin
@tanstack/eslint-plugin-router
@tanstack/history
@tanstack/nitro-v2-vite-plugin
@tanstack/react-router
@tanstack/react-router-devtools
@tanstack/react-router-ssr-query
@tanstack/react-start
@tanstack/react-start-client
@tanstack/react-start-server
@tanstack/router-cli
@tanstack/router-core
@tanstack/router-devtools
@tanstack/router-devtools-core
@tanstack/router-generator
@tanstack/router-plugin
@tanstack/router-ssr-query-core
@tanstack/router-utils
@tanstack/router-vite-plugin
@tanstack/server-functions-plugin
@tanstack/solid-router
@tanstack/solid-router-devtools
@tanstack/solid-start
@tanstack/solid-start-client
@tanstack/solid-start-server
@tanstack/start-client-core
@tanstack/start-plugin-core
@tanstack/start-server-core
@tanstack/start-static-server-functions
@tanstack/start-storage-context
@tanstack/valibot-adapter
@tanstack/virtual-file-routes
@tanstack/zod-adapter
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/start-client-core/src/client-rpc/serverFnFetcher.ts
(2 hunks)packages/start-client-core/src/constants.ts
(1 hunks)packages/start-client-core/src/createServerFn.ts
(1 hunks)packages/start-client-core/src/index.tsx
(1 hunks)packages/start-client-core/src/tests/createServerFn.test-d.ts
(2 hunks)packages/start-server-core/src/server-functions-handler.ts
(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript in strict mode with extensive type safety across the codebase
Files:
packages/start-client-core/src/createServerFn.ts
packages/start-client-core/src/constants.ts
packages/start-client-core/src/client-rpc/serverFnFetcher.ts
packages/start-client-core/src/tests/createServerFn.test-d.ts
packages/start-server-core/src/server-functions-handler.ts
packages/start-client-core/src/index.tsx
packages/{*-start,start-*}/**
📄 CodeRabbit inference engine (AGENTS.md)
Name and place Start framework packages under packages/-start/ or packages/start-/
Files:
packages/start-client-core/src/createServerFn.ts
packages/start-client-core/src/constants.ts
packages/start-client-core/src/client-rpc/serverFnFetcher.ts
packages/start-client-core/src/tests/createServerFn.test-d.ts
packages/start-server-core/src/server-functions-handler.ts
packages/start-client-core/src/index.tsx
🧬 Code graph analysis (4)
packages/start-client-core/src/constants.ts (1)
packages/start-client-core/src/index.tsx (1)
X_TSS_RAW_RESPONSE
(88-88)
packages/start-client-core/src/client-rpc/serverFnFetcher.ts (2)
packages/start-client-core/src/constants.ts (1)
X_TSS_RAW_RESPONSE
(8-8)packages/start-client-core/src/index.tsx (1)
X_TSS_RAW_RESPONSE
(88-88)
packages/start-client-core/src/tests/createServerFn.test-d.ts (1)
packages/start-client-core/src/createServerFn.ts (1)
createServerFn
(51-170)
packages/start-server-core/src/server-functions-handler.ts (2)
packages/start-client-core/src/constants.ts (1)
X_TSS_RAW_RESPONSE
(8-8)packages/start-client-core/src/index.tsx (1)
X_TSS_RAW_RESPONSE
(88-88)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
result.result.headers.set(X_TSS_RAW_RESPONSE, 'true') | ||
return result.result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting a header on an immutable Response will throw at runtime
When developers return a Response obtained from fetch
(very common for proxying upstream resources), response.headers
is immutable. Calling set
on it throws TypeError: Headers guard is immutable
, so this path will crash before the response ever reaches the client—precisely the scenario this PR is meant to fix. Instead of mutating the existing headers, clone them (and the response metadata) into a new Response that includes X_TSS_RAW_RESPONSE
.
Apply this diff to fix the issue:
- if (result.result instanceof Response) {
- result.result.headers.set(X_TSS_RAW_RESPONSE, 'true')
- return result.result
- }
+ if (result.result instanceof Response) {
+ const rawResponse = result.result
+ const headers = new Headers(rawResponse.headers)
+ headers.set(X_TSS_RAW_RESPONSE, 'true')
+ return new Response(rawResponse.body, {
+ status: rawResponse.status,
+ statusText: rawResponse.statusText,
+ headers,
+ })
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
result.result.headers.set(X_TSS_RAW_RESPONSE, 'true') | |
return result.result | |
if (result.result instanceof Response) { | |
const rawResponse = result.result | |
const headers = new Headers(rawResponse.headers) | |
headers.set(X_TSS_RAW_RESPONSE, 'true') | |
return new Response(rawResponse.body, { | |
status: rawResponse.status, | |
statusText: rawResponse.statusText, | |
headers, | |
}) | |
} |
🤖 Prompt for AI Agents
In packages/start-server-core/src/server-functions-handler.ts around lines
149-150, the code attempts to call result.result.headers.set(...) on a Response
returned from fetch, but fetch Responses have immutable headers and calling set
throws at runtime; instead, create a new Response cloning the original body and
metadata and use a mutable copy of the headers: construct a new
Headers(result.result.headers), call set('X-TSS-RAW_RESPONSE','true') on that
copy, then return new Response(result.result.body, { status:
result.result.status, statusText: result.result.statusText, headers:
headersCopy, /* copy any other relevant properties like duplex if used */ });
this avoids mutating the original immutable Headers and preserves the original
response metadata and body.
fixes #5271
fixes #5255
Summary by CodeRabbit
New Features
Tests