Skip to content

Next.js 16 Turbopack: route handler spans lost via tRPC fetchRequestHandler — auto-wrapping needed #20782

@timothyclin

Description

@timothyclin

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nextjs

SDK Version

10.52.0

Framework Version

Next.js 16.2.4 (Turbopack), @sentry/nextjs 10.52.0, @trpc/server 11.17.0.

Link to Sentry event

https://t14c.sentry.io/explore/traces/trace/f6d797128c3e30fcdd8cd428d281f216/?end=2026-05-12T04%3A29%3A35&node=span-2b554e5309ada4c5&pageEnd=2026-05-12T04%3A29%3A35.000&pageStart=2026-05-09T04%3A29%3A35.000&project=-1&query=trace%3Af6d797128c3e30fcdd8cd428d281f216&search=project%3Ainspectionjarvis-dev&source=traces&start=2026-05-09T04%3A29%3A35&targetId=2b554e5309ada4c5&timestamp=1778430575

Reproduction Example/SDK Setup

Problem:
Under Turbopack, withSentryConfig only injects values into the instrumentation file — it does not add a wrapping loader for route handlers (unlike the webpack path, which calls wrapRouteHandlerWithSentry via wrappingLoader.ts). Since tRPC's fetchRequestHandler introduces an async boundary that loses OpenTelemetry context, all child spans — whether manual (startSpan, startInactiveSpan) or via Sentry.trpcMiddleware — become orphaned. They never appear in Performance traces.
What we see: every trace is middleware GET / middleware POST with no children. No visibility into procedure-level latency, file upload duration, or rules engine timing.
What we tried (none work):

  1. Sentry.startSpan directly in exported route handler — compiled away by Turbopack
  2. Wrapper function around the handler — return types break Next.js route constraints
  3. Sentry.trpcMiddleware (from @sentry/node) — creates rpc.server spans but they never appear because no parent context exists
  4. NEXT_OTEL_VERBOSE=1 — Next.js emits more native spans but Sentry's handleOnSpanStart renames them all to middleware GET/POST
    What helps:
    Adding a Turbopack wrapping loader rule to constructTurbopackConfig.ts that mirrors what wrappingLoader.ts does for webpack, so route handlers maintain the Sentry scope chain across tRPC's async boundary. Alternatively, restoring the wrapRouteHandlerWithSentry wrapping through the Turbopack plugin system would fix this for all App Router users.

Steps to Reproduce

  1. Create Next.js 16 App Router project with Turbopack (default)
  2. Install @sentry/nextjs 10.52.0, @trpc/server 11.17.0
  3. Set up Sentry via instrumentation.ts + sentry.*.config.ts (standard manual setup)
  4. Create a tRPC router with a simple procedure that calls Sentry.startSpan
  5. Export GET/POST handlers using fetchRequestHandler
  6. npm run build && npm start
  7. Send a tRPC request
  8. Open Sentry Performance → traces

Expected Result

trace shows "tRPC handler" / "trpc/hello" with child spans

Actual Result

trace shows "middleware POST" with no children

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.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions