#8280·router

Start: non-OK application/json response makes a server function resolve undefined instead of rejecting

Author: antur84Created Sep 7, 2026Updated Sep 10, 2026
Labelsinformation needed

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:

typescript
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

  1. pnpm install && pnpm build && pnpm start
  2. Open http://localhost:3000/?mode=json500. The fetch returns a 500 JSON body. The loader resolves with undefined.
  3. Open http://localhost:3000/?mode=text500. Same 500 as text/plain. The loader rejects.
  4. Open http://localhost:3000/?mode=noheader. Real request without x-tsr-serverFn. The server answers {"status":500,"unhandled":true,"message":"HTTPError"}, the loader resolves with undefined.

Expected behavior

A non-OK response that Start did not serialize should reject, like the text/plain path:

typescript
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.