createServerFn gets tree-shaken when only called server-side
Which project does this relate to?
Start
Describe the bug
When a createServerFn is only called from a createFileRoute handler (server-side) and not use in any client-side code, it gets tree-shaken during production build, causing runtime errors.
Reproduction
// src/routes/api.ts
const serverFn = createServerFn({ method: "POST" })
.handler(async ({ data }) => {
console.log("This never runs"); // ❌ Never executes
// ...
});
export const Route = createFileRoute("/api")({
server: {
handlers: {
POST: async ({ request }) => {
serverFn(); // ❌ throw 500
// ...
},
},
},
});
Environment
@tanstack/react-start: ^1.139.8 vite: ^7.1.7 Build target: Production (works fine in dev mode)
Your Example Website or App
//
Steps to Reproduce the Bug or Issue
//
Expected behavior
//
Screenshots or Videos
No response
Platform
//
Additional context
No response
that's by design really. if you are only calling it from server side, dont use a server function then?
I see a similar problem in my codebase, I have a shared utils library with a server function, and 2 applications, one is calling the server function from the client, and the other only calls it from another server function, so the later failed on runtime, where the function manifest on the server side is missing the lib server function id.
It used to work at version 1.133, what should I do then? should I export the internal function of the server function as a server only function and use it in the server functions? isn't the concept of server function that it can run from both server and client?
BTW, the documentation says clearly that server function can be used in other server functions https://tanstack.com/start/latest/docs/framework/react/guide/server-functions#where-to-call-server-functions and it's not stated at all that in order to use a server function inside another server function, the inner server function must also be used in a client code so it won't be eliminated.
BTW, in my case it looks something like this (which is a common pattern as well)
// src/routes/home.ts
const innerFn = createServerFn({ method: "POST" })
.handler(async ({ data }) => {
console.log("This never runs"); // ❌ Never executes
// ...
});
const outerFn = createServerFn({ method: "POST" })
.handler(async ({ data }) => {
console.log("This runs");
await innerFn(); // ❌ This crashes because innerFn does not exist in the server function manifest
// ...
});
export const Route = createFileRoute("/home")({
loader: async () => {
await outerFn();
},
...
});
Any update here? We had/have the same issue as we were under the impression that server functions can also be used if they are never called client side. In previous versions this also worked.
We are fine either way - but it would be good to understand if this is indeed a bug that will be fixed in the future or if this is indeed by design, as the documentation is a bit ambigous:
Server functions let you define server-only logic that can be called from anywhere in your application - loaders, components, hooks, or other server functions.
working on that. will be fixed soon