Skip to content

TanStack Start + Vercel: No server-side errors/logs/traces with @sentry/tanstackstart-react (alpha) #19458

Closed

Description

@masinette

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/tanstackstart-react

SDK Version

/

Framework Version

No response

Link to Sentry event

No response

Reproduction Example/SDK Setup

instrument.server.mjs


import * as Sentry from '@sentry/tanstackstart-react'
import { pinoIntegration } from '@sentry/node'

const sentryDsn = process.env.VITE_SENTRY_DSN
const appEnv = process.env.VITE_APP_ENV
const isDevelopment = process.env.NODE_ENV === 'development'

try {

  if (!sentryDsn) {
    console.warn('VITE_SENTRY_DSN is not defined. Sentry is not running.')
  } else {
    // Build integrations list - exclude profiling in development
    const integrations = [
      // Capture pino logs as Sentry breadcrumbs and send errors to Sentry
      // https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/pino/
      pinoIntegration(),
    ]
  
    // Only load profiling in non-development environments
    if (!isDevelopment) {
      const { nodeProfilingIntegration } = await import('@sentry/profiling-node')
      integrations.push(nodeProfilingIntegration())
    }
  
    Sentry.init({
      dsn: sentryDsn,
      // Adds request headers and IP for users, for more info visit:
      // https://docs.sentry.io/platforms/javascript/guides/tanstackstart-react/configuration/options/#sendDefaultPii
      sendDefaultPii: false,
      tracesSampleRate: 1.0,
      // Set sampling rate for profiling - this is relative to tracesSampleRate
      profilesSampleRate: isDevelopment ? 0 : 1.0,
      profileLifecycle: 'trace',
      replaysSessionSampleRate: 1.0,
      replaysOnErrorSampleRate: 1.0,
      enabled: !isDevelopment,
      environment: appEnv,
      integrations,
      enableLogs: true,
    })
  }
}
catch (error) {
  console.error('Error initializing Sentry', error)
}

package.json

{
  "name": "web-app",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "dotenv -e .env.local -- sh -c \"NODE_OPTIONS='--import ./instrument.server.mjs' vite dev --port 3001\"",
    "build": "vite build && cp instrument.server.mjs .vercel/server",
    "build:local": "vite build && cp instrument.server.mjs .output/server",
    "preview": "vite preview",
    "test": "bun test",
    "seed": "./scripts/seed.sh",
    "seed:stripe": "./scripts/seed-stripe.sh",
    "test:coverage": "bun test --coverage",
    "format": "biome format --fix",
    "lint": "biome lint",
    "check": "biome check",
    "start": "node --import ./.vercel/server/instrument.server.mjs .vercel/server/index.mjs",
    "get-env": "npx vercel env pull -y --environment=${VERCEL_ENV:-development} .env.${VERCEL_ENV:-development}.local"
  },
  "dependencies": {
    "@fontsource-variable/archivo": "catalog:ui",
    "@sentry/profiling-node": "catalog:devtools",
    "@sentry/tanstackstart-react": "catalog:devtools",
    "@tanstack/react-devtools": "catalog:tanstack",
    "@tanstack/react-query": "catalog:tanstack",
    "@tanstack/react-query-devtools": "catalog:tanstack",
    "@tanstack/react-router": "catalog:tanstack",
    "@tanstack/react-router-devtools": "catalog:tanstack",
    "@tanstack/react-router-ssr-query": "catalog:tanstack",
    "@tanstack/react-start": "catalog:tanstack",
    "@tanstack/router-plugin": "catalog:tanstack",
    "@tailwindcss/vite": "catalog:ui",
    "@vercel/analytics": "catalog:analytics",
    "@workspace/auth": "*",
    "@workspace/billing": "*",
    "@workspace/database": "*",
    "@workspace/emails": "*",
    "@workspace/logger": "*",
    "@workspace/seo": "*",
    "@workspace/slack": "*",
    "@workspace/ui": "*",
    "date-fns": "catalog:date",
    "date-fns-tz": "catalog:date",
    "dotenv-cli": "^11.0.0",
    "hono":"catalog:devtools",
    "lucide-react": "catalog:ui",
    "nitro": "catalog:build",
    "posthog-js": "catalog:analytics",
    "react": "catalog:ui",
    "react-dom": "catalog:ui",
    "vite-tsconfig-paths": "catalog:build"
  },
  "devDependencies": {
    "@workspace/test-utils": "*",
    "dotenv": "catalog:devtools",
    "@biomejs/biome": "catalog:devtools",
    "@tanstack/devtools-vite": "catalog:tanstack",
    "@testing-library/dom": "catalog:testing",
    "@testing-library/react": "catalog:testing",
    "@types/node": "catalog:types",
    "@types/react": "catalog:types",
    "@types/react-dom": "catalog:types",
    "@vitejs/plugin-react": "catalog:build",
    "babel-plugin-react-compiler": "catalog:build",
    "jsdom": "catalog:testing",
    "typescript": "catalog:types",
    "vite": "catalog:build",
    "vitest": "catalog:build",
    "web-vitals": "catalog:testing"
  }
}

Steps to Reproduce

User's question:

I’m using TanStack Start with Sentry via @sentry/tanstackstart-react and seeing correct behavior locally, but when deploying to Vercel I don’t get any server-side issues, logs, or traces in Sentry. Client-side reporting works as expected.

I’ve followed the TanStack Start + Sentry docs, including the server instrumentation setup. [[TanStack Start guide](https://docs.sentry.io/platforms/javascript/guides/tanstackstart-react/#configure-server-side-sentry)]

Steps to Reproduce

  1. Create a new TanStack Start project.
  2. Install and configure @sentry/tanstackstart-react as above
  3. Deploy the app to Vercel using the standard TanStack Start Vercel deployment flow.
  4. Trigger an error
  5. Check Sentry for:
    • error events
    • logs
    • traces

Expected Result

  • Server-side errors, logs, and traces appear in Sentry for the Vercel deployment, similar to local behavior.
  • Manual calls like Sentry.captureException and Sentry.captureMessage from server code should reliably show up in Sentry when deployed to Vercel.

Actual Result

  • Locally:
    • Server-side Sentry behavior works as expected.
  • On Vercel:
    • No server-side issues/logs/traces appear in Sentry.
    • Client-side events still work.

Additional Context

No response

Priority

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.

Activity

  1. linear commented on Feb 20, 2026

    @linear
  2. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Feb 20, 2026
  3. masinette commented on Feb 20, 2026

    @masinette
    MemberAuthor
  4. self-assigned this
    on Feb 23, 2026
  5. JPeer264 commented on Feb 23, 2026

    @JPeer264
    Member

    Yes, this SDK is still in alpha. It is confirmed that this is not working. For the server part on Vercel, that is unfortunately harder, as Vercel doesn't allow to add the --import flag to actually hook our instrumentations in (TanStack Start's output is ESM). The client bundle is independent of the vendor it is deployed on. I'll cross check internally if there are some workarounds for this

  6. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Feb 23, 2026
  7. Axadali commented on Feb 24, 2026

    @Axadali

    Hi @JPeer264,

    I’ve been looking into this issue and wanted to share some observations:

    What I think is happening:

    • Locally, the --import ./instrument.server.mjs works, so Sentry is initialized before any server code runs.
    • On Vercel, serverless functions don’t allow --import, so the server-side initialization is skipped.
    • Client-side Sentry works fine because it’s independent of the server environment.
    • The alpha SDK currently seems to assume a long-running Node process for server instrumentation, which doesn’t align with serverless lifecycles.

    Other considerations:

    • ESM output may require dynamic imports for some Node integrations (like profiling).
    • Global error listeners (process.on('unhandledRejection')) might not persist in serverless invocations.
    • Correct env variables (VITE_SENTRY_DSN, VITE_APP_ENV) are needed in production.

    It seems like the main blocker is the inability to preload Sentry on Vercel serverless functions, which explains why server-side events don’t appear.

    Just wanted to share my thoughts—hopefully this context is useful while investigating potential workarounds.

  8. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Feb 24, 2026
  9. JPeer264 commented on Feb 24, 2026

    @JPeer264
    Member

    On Vercel, serverless functions don’t allow --import, so the server-side initialization is skipped.

    Exactly that is happening

    The alpha SDK currently seems to assume a long-running Node process for server instrumentation, which doesn’t align with serverless lifecycles.

    Could you elaborate on that? Are there specifics which we could improve to make it work better for serverless lifecycles?

  10. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Feb 24, 2026
  11. Axadali commented on Feb 24, 2026

    @Axadali

    Some ways the SDK could work better for serverless:

    • Initialize per request: Set up Sentry inside each serverless handler.
    • Use a global guard: Prevent multiple initializations during a single function invocation (e.g., global.__sentry_initialized__).
    • Flush events before exit: Call Sentry.flush() at the end of each request to ensure errors and traces are sent.
    • Avoid long-lived buffers: Profiling, tracing, or logging integrations should be request-scoped, not rely on a persistent process.

    In short, making Sentry initialization and cleanup request-scoped would make it much more compatible with serverless lifecycles like Vercel’s.

  12. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Feb 24, 2026
  13. JPeer264 commented on Feb 24, 2026

    @JPeer264
    Member

    Thanks for the details. We'll keep an eye on these points

  14. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Feb 24, 2026
  15. nicohrubec commented on Feb 24, 2026

    @nicohrubec
    Member

    We investigated this a bit more. It should work to get errors and basic tracing by importing instrument.server.mjs (first import) in server.ts and add a flush call. So the server.ts file should look something like this:

    import '../instrument.server.mjs';
    import { wrapFetchWithSentry, flush } from '@sentry/tanstackstart-react';
    
    import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
    
    const requestHandler = wrapFetchWithSentry({
      async fetch(request: Request) {
        try {
          return await handler.fetch(request);
        } finally {
          await flush();
        }
      },
    });
    
    export default createServerEntry(requestHandler);
    
  16. removed their assignment
    on Mar 9, 2026
  17. moved this to Waiting for: Support in GitHub Issues with 👀 3on Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions