Start: non-OK application/json response makes a server function resolve undefined instead of rejecting
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.1k
- Forks
- 1.9k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 143
Description
Which project does this relate to?
Start
Describe the bug
A server-function call resolves with undefined when the response is not OK, is application/json, and has no x-tss-serialized header. .catch() never runs. The same 500 as text/plain rejects.
getResponse in start-client-core/src/client-rpc/serverFnFetcher.ts returns plain JSON before it checks response.ok:
if (contentType.includes('application/json')) {
const jsonPayload = await response.json()
const redirect = parseRedirect(jsonPayload)
if (redirect) throw redirect
if (isNotFound(jsonPayload)) throw jsonPayload
return jsonPayload
}
if (!response.ok) {
throw new Error(await response.text())
}
The middleware in createServerFn.ts spreads that body into the call context and returns result.result, so an error body without a result key becomes undefined. A body with an error key is thrown as-is.
Any JSON error response between browser and server does this: a gateway 502 page, a proxy, or the server's own unhandled 500 when x-tsr-serverFn is missing (#8237).
Complete minimal reproducer
https://github.com/antur84/tanstack-start-serverfn-nonok-json-repro
Steps to Reproduce the Bug
pnpm install && pnpm build && pnpm start- Open http://localhost:3000/?mode=json500. The fetch returns a 500 JSON body. The loader resolves with
undefined. - Open http://localhost:3000/?mode=text500. Same 500 as
text/plain. The loader rejects. - Open http://localhost:3000/?mode=noheader. Real request without
x-tsr-serverFn. The server answers{"status":500,"unhandled":true,"message":"HTTPError"}, the loader resolves withundefined.
Expected behavior
A non-OK response that Start did not serialize should reject, like the text/plain path:
if (!response.ok) throw new Error(JSON.stringify(jsonPayload))
Screenshots or Videos
None, the banner on each page shows the outcome.
Platform
@tanstack/react-start 1.168.50, @tanstack/react-router 1.170.33 (start-client-core 1.170.28, start-server-core 1.169.32, router-core 1.171.28), vite 8.2.2, node 24, macOS. Same code on main.
Additional context
Fixing #8237 does not close this. Any JSON error body takes the same path.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in start-client-core/src/client-rpc/serverFnFetcher.ts, focusing on getResponse and its application/json handling, then review the related middleware in createServerFn.ts. Run the linked reproducer with pnpm install && pnpm build && pnpm start and compare json500 with text500. Done means non-OK, unserialized JSON responses reject instead of resolving undefined.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100