TanStack / TanStack/router

TanStack Start server functions should return 404 when requested with an invalid ID, currently 500

Open
#7,363 1 comment 7 reactions 0 assignees View on GitHub

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

Server functions live at the /_serverFn/$id route, and they work well. If the build changes, the IDs change - this is good.

However, when a server function is requested at an old ID that no longer exists, the framework returns a 500 and you'll see a bunch of associated logging for the stack trace.

This is causing me, and presumably others, issues when deploying to production because these 500s trigger alerts etc. when they are in fact erroneous. Any other instance of a missing resource would be treated as a 404.

The cause of the issues in production comes from caching. Some of this we can control as website publishers, but some of it we can't. For example, I am currently being repeatedly hit by BingBot during its routine indexing operations (which I want) but it caches and follows server function routes in ways that don't seem to always abide by headers or TTLs. Each time it hits an old server function route that it has discovered and cached from a previous load, I'll get a 500 error.

I've personally worked around this by:

  • adding more specific caching headers to the root, route, asset and serverFn routes
  • adding more specific robot.txt instructions to disallow serverFn routes
  • adding middleware to suppress the "Server function info not found" 500 errors and turn them into 404s

These three things are things that I think the framework should do for you.

Complete minimal reproducer

https://github.com/neverstew/server-fn-500s

Steps to Reproduce the Bug
  1. Create an empty project - I used the basic template from the docs
  2. Build it with npm run build
  3. Preview with npx vite preview
  4. curl -i http://localhost:3000/_serverFn/test
neverstew@mattbook ~/d/a/start-basic> curl -i http://localhost:3000/_serverFn/test
HTTP/1.1 500 Internal Server Error
Vary: Origin
content-type: application/json;charset=UTF-8
content-length: 53
Date: Thu, 07 May 2026 21:14:00 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"status":500,"unhandled":true,"message":"HTTPError"}⏎
neverstew@mattbook ~/d/a/start-basic> npx vite preview

 ╭────────── [Build Info] ────────────╮
 │                                    │
 │  - Build Directory: .output        │
 │  - Date: 07/05/2026, 22:13:44      │
 │  - Nitro Version: 3.0.260311-beta  │
 │  - Nitro Preset: node-server       │
 │                                    │
 ╰────────────────────────────────────╯

  ➜  Local:   http://localhost:3000/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
Error: Server function info not found for test
    at getServerFnById (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:144:27)
    ... 8 lines matching cause stack trace ...
    at async Object.fetch (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1586:10) {
  cause: Error: Server function info not found for test
      at getServerFnById (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:144:27)
      at handleServerAction (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:587:23)
      at file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1411:15
      at AsyncLocalStorage.run (node:internal/async_local_storage/async_context_frame:63:14)
      at runWithStartContext (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:199:22)
      at serverFnHandler (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1404:13)
      at next (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1261:19)
      at executeMiddleware (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1279:9)
      at startRequestResolver (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1417:42)
      at async Object.fetch (file:///Users/neverstew/dev/abitat/start-basic/.output/server/_ssr/ssr.mjs:1586:10),
  status: 500,
  statusText: undefined,
  headers: undefined,
  data: undefined,
  body: undefined,
  unhandled: true
}
Expected behavior

A nicely handled response with something informative and a 404 status.
No stack trace in the logs.

Screenshots or Videos

No response

Platform
  • Router / Start Version: 1.167.65
  • OS: macOS, Linux, (presumably Windows - untested)
  • Browser: N/A
  • Bundler: vite
  • Bundler Version: 8.0.0
Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the request to /_serverFn/test with npm run build, npx vite preview, and curl, then trace the server-function handling described in the stack trace. Done means an invalid server-function ID returns an informative 404 response without a 500 status or stack-trace logging.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vite
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.