T
TanStack•3d ago
extended-salmon

How to return 404 status from Server Function without breaking the response payload?

Hi! I'm encountering an issue when trying to return a 404 status from a createServerFn. When I use setResponseStatus(404) and then throw an error, instead of receiving the error payload in the client, the server returns a generic HTML 404 page saying "Cannot GET /_serverFn/...". It seems like setting the 404 status causes the underlying server to treat the server function endpoint itself as "not found", masking the actual application error I want to send.
export const getClientPersonalInformation = createServerFn({ method: 'GET' })
.inputValidator(z.uuid())
.handler(async ({ data: clientId }) => {
const personalInfo = await service.getPersonalInformation(clientId)

if (!personalInfo) {
// This triggers the HTML response issue
setResponseStatus(404)
throw new Error('Personal information not found')
}

return personalInfo
})
export const getClientPersonalInformation = createServerFn({ method: 'GET' })
.inputValidator(z.uuid())
.handler(async ({ data: clientId }) => {
const personalInfo = await service.getPersonalInformation(clientId)

if (!personalInfo) {
// This triggers the HTML response issue
setResponseStatus(404)
throw new Error('Personal information not found')
}

return personalInfo
})
The response I get in the frontend (Network tab):
<!DOCTYPE html>
<html lang="en">
<head>
<title>Error</title>
</head>
<body>
<pre>Cannot GET /_serverFn/eyJmaWxlIjoiL0BpZC9zcmMvcm91dGVzL2JhY2tvZmZpY2UvY2xpZW50cy8tYXBpLnRzP3Rzci1kaXJlY3RpdmUtdXNlLXNlcnZlcj0iLCJleHBvcnQiOiJnZXRDbGllbnRQZXJzb25hbEluZm9ybWF0aW9uX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ</pre>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Error</title>
</head>
<body>
<pre>Cannot GET /_serverFn/eyJmaWxlIjoiL0BpZC9zcmMvcm91dGVzL2JhY2tvZmZpY2UvY2xpZW50cy8tYXBpLnRzP3Rzci1kaXJlY3RpdmUtdXNlLXNlcnZlcj0iLCJleHBvcnQiOiJnZXRDbGllbnRQZXJzb25hbEluZm9ybWF0aW9uX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ</pre>
</body>
</html>
How can I correctly return a 404 status code (to indicate resource not found) from a Server Function without triggering the default server 404 HTML page, so I can handle the error message in the client? Another really frustrating issue is that even if I define a notFoundComponent on my routes, the 404 error thrown from the server function never triggers it. This happens regardless of whether I use setResponseStatus(404) or throw notFound(). The router simply doesn't seem to catch these server-side 404s to render the notFoundComponent as expected. I'm starting to suspect this might be a bug or a missing piece in the integration between TanStack Start Server Functions and the Router's notFound handling.
3 Replies
continuing-cyan
continuing-cyan•3d ago
you can send responses directly from server functions, could work? try:
return new Response(JSON.stringify({
error: { someerr: "testing" }
}), {
status: 404,
headers: {
'Content-Type': 'application/json',
}
})
return new Response(JSON.stringify({
error: { someerr: "testing" }
}), {
status: 404,
headers: {
'Content-Type': 'application/json',
}
})
extended-salmon
extended-salmonOP•2d ago
Same result 😩:
Cannot GET /_serverFn/eyJmaWxlIjoiL0BpZC9zcmMvcm91dGVzL2JhY2tvZmZpY2UvY2xpZW50cy8tYXBpLnRzP3Rzci1kaXJlY3RpdmUtdXNlLXNlcnZlcj0iLCJleHBvcnQiOiJnZXRDbGllbnRQZXJzb25hbEluZm9ybWF0aW9uX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ
Cannot GET /_serverFn/eyJmaWxlIjoiL0BpZC9zcmMvcm91dGVzL2JhY2tvZmZpY2UvY2xpZW50cy8tYXBpLnRzP3Rzci1kaXJlY3RpdmUtdXNlLXNlcnZlcj0iLCJleHBvcnQiOiJnZXRDbGllbnRQZXJzb25hbEluZm9ybWF0aW9uX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ
extended-salmon
extended-salmonOP•2d ago
And it gets worse — when you hit the URL that should return a 404 directly, the server crashes and never recovers.
No description

Did you find this page helpful?