TanStackT
TanStack2mo ago
7 replies
progressive-amaranth

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
  })


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>


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.
Was this page helpful?