router icon indicating copy to clipboard operation
router copied to clipboard

createServerFn gets tree-shaken when only called server-side

Open Dzinlife opened this issue 1 month ago • 3 comments

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

Dzinlife avatar Nov 26 '25 16:11 Dzinlife

that's by design really. if you are only calling it from server side, dont use a server function then?

schiller-manuel avatar Nov 29 '25 20:11 schiller-manuel

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?

sharonyogev avatar Nov 30 '25 19:11 sharonyogev

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();
  },
  ...
});

sharonyogev avatar Dec 01 '25 09:12 sharonyogev

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.

christopher-wittlinger avatar Dec 19 '25 07:12 christopher-wittlinger

working on that. will be fixed soon

schiller-manuel avatar Dec 19 '25 10:12 schiller-manuel