2026-09-23·Chiheb Nabil

TanStack Start Server Function Failing With No Logs? (2026 Fix)

Your createServerFn throws, the UI shows a generic error, and your host logs show nothing. Why TanStack Start server functions fail silently — and how to capture every error with one middleware.

tanstack-startdebuggingserver-functionsloggingobservability

Your TanStack Start server function throws. The UI shows a generic error boundary. You open your host dashboard — Vercel, Netlify, Cloudflare — and find... nothing useful. No stack trace, no function name, no input that triggered it.

This is the most common TanStack Start debugging story on GitHub discussions, Netlify answers, and Reddit: "server function failing with no logs." Here's why it happens and the one-middleware fix.

Why server function errors go missing

createServerFn runs on the server, but the failure surfaces on the client. Three gaps swallow the evidence:

  1. The client only gets a digest. When a server function throws, TanStack Start serializes a minimal error to the client. The real stack trace stays on the server — where nobody logged it.
  2. No logging is wired by default. Server functions don't log their inputs, duration, or errors unless you add it. An unhandled throw inside createServerFn produces exactly one artifact: a 500 response.
  3. Host logs expire or scatter. On Vercel Hobby, runtime logs vanish after 1 hour. On Cloudflare Workers, a crash before your code runs (Error 1101) emits nothing at all. On Netlify, server function logs live in a separate UI from your site logs — the exact "no logs" thread that keeps resurfacing.

The result: you know which button broke, but not which function, which input, or which line.

The fix: one middleware, every server function covered

TanStack Start supports request middleware via createStart. FlareLog's tanstackStartMiddleware hooks into it and logs every server function call — inputs, duration, outcome, and full errors with stack traces:

// src/start.ts
import { createStart } from "@tanstack/react-start";
import { flarelog } from "@flarelog/sdk";
import { tanstackStartMiddleware } from "@flarelog/sdk/tanstack-start";

const logger = flarelog({
  apiKey: process.env.FLARELOG_API_KEY,
});

export const startInstance = createStart(() => ({
  requestMiddleware: [
    tanstackStartMiddleware(logger) as never,
  ],
}));

That's the whole setup. Every createServerFn call now emits a structured log: function name, input data, duration, and — on failure — the error with stack trace, searchable in your dashboard by function name or traceId.

For individual functions: wrap with context

For critical server functions (payments, mutations, external API calls), wrap them directly to attach business context:

// src/routes/api/orders.ts
import { createServerFn } from "@tanstack/react-start";
import { withTanStackStart } from "@flarelog/sdk/tanstack-start";
import { logger } from "../start";

// Wrap any server function — errors auto-captured
export const fetchOrder = createServerFn(
  withTanStackStart(logger, async ({ data }) => {
    const ctx = withTanStackStart.getContext();
    ctx.logger.info("Looking up order", { orderId: data.id });

    const order = await db.orders.findById(data.id);
    if (!order) {
      ctx.logger.warn("Order not found", { orderId: data.id });
      throw new Error("NOT_FOUND");
    }
    return order;
  })
);

Now the "order lookup failed" error arrives with the orderId that triggered it — the difference between a 2-minute fix and a 2-hour reproduction hunt.

Don't forget the client side

Server functions are half the story. When the client component that called the function also crashes (bad response shape, null access on the result), catch that with an error boundary:

// src/ErrorBoundary.tsx
import { flarelog } from "@flarelog/sdk";
import { FlareLogErrorBoundary } from "@flarelog/sdk/react";

const logger = flarelog({
  apiKey: process.env.NEXT_PUBLIC_FLARELOG_API_KEY,
});

export function RootErrorBoundary({ children }) {
  return (
    <FlareLogErrorBoundary
      logger={logger}
      fallback={<ErrorPage />}
    >
      {children}
    </FlareLogErrorBoundary>
  );
}

Server errors and client errors land in the same dashboard, correlated by traceId. The full request lifecycle — client click → server function → database → error — reads as one story.

Common TanStack Start silent-failure patterns

Pattern 1: Thrown object isn't an Error

// Bad: loses the stack trace everywhere
throw { code: "NOT_FOUND" };

// Good: real Error, real stack, searchable
throw new Error("NOT_FOUND");

Middleware can only capture what the runtime preserves. Plain-object throws serialize to {} across the server/client boundary on some hosts.

Pattern 2: Missing env var on the host, present locally

Your .env.local has DATABASE_URL; the host doesn't. The server function throws on first DB call, and the host log (if it still exists) shows a minified digest. Validate env at startup and log it:

if (!process.env.DATABASE_URL) {
  logger.error("DATABASE_URL is not set — check host env vars");
  throw new Error("Misconfigured host environment");
}

Pattern 3: Deployed to Workers via Lovable — crash before logging

If your TanStack Start app was generated by Lovable and runs on Cloudflare Workers, CPU/memory kills destroy the Worker before any SDK fires. That's Error 1101 territory — read the Lovable crash guide for the Tail Worker fix that captures crashes outside your app.

Query it from your AI editor

Connect the FlareLog MCP server once, then ask Cursor or Claude in plain English: "What server function errors happened in the last hour?" No copy-pasting stack traces:

{
  "mcpServers": {
    "flarelog": {
      "url": "https://mcp.flarelog.dev",
      "headers": {
        "Authorization": "Bearer fl_your_api_key_here"
      }
    }
  }
}

Stop debugging server functions blind

If your createServerFn keeps failing and the logs show nothing, the problem usually isn't your code — it's that nothing is capturing the failure. One middleware fixes it permanently.

Start free — 10k logs/month, 90-day retention, no credit card. Or read the TanStack Start setup guide for the full walkthrough.

Keep going

Never miss an invisible crash again

FlareLog catches the errors Cloudflare can't log. Set up the Tail Worker in 5 minutes and see every crash, timeout, and cost spike in real time.

Start free →