nextjs - ✅(Solved) Fix Unhandled errors within a Suspense aren't appearing consistently in OTEL traces/spans [3 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#86517Fetched 2026-04-08 02:10:29
View on GitHub
Comments
1
Participants
2
Timeline
19
Reactions
1
Author
Timeline (top)
referenced ×10cross-referenced ×3labeled ×2closed ×1

Error Message

  1. Trigger the error by interacting with the app: http://localhost:3000
  2. Click on the Expected tracing behaviour (with span error) link to see the expected behavior where the span records the error: http://localhost:3000/expected
  3. Click on the Unexpected tracing behaviour (without span error) link to see the unexpected behavior where the span does not record the error: http://localhost:3000/not-expected
  4. [optional] Click on the Expected tracing behaviour without suspense (with span error) link to see the expected behavior without Suspense where the span records the error: http://localhost:3000/no-suspense

Expected, with error event:

Actual, without error event:

If the error in the suspense boundary occurs before the page has been rendered, then the span is attributed with the error event as expected. If the error occurs after the page has been rendered, then the span isn't attributed with the error event.

Fix Action

Fixed

PR fix notes

PR #86595: Fix: Unhandled errors within a Suspense aren't appearing consistently in OTEL traces/spans

Description (problem / solution / changelog)

Fixes #86517

The root cause is likely in Next.js's instrumentation layer where async Suspense boundaries don't properly maintain span context for delayed errors. We need to modify the instrumentation to ensure error handlers remain attached to the active span context even after the initial render completes. This involves extending span lifecycle management for Suspense boundaries and ensuring error events are properly propagated to parent spans when caught by error boundaries within Suspense.

AI Analysis

This is an OpenTelemetry instrumentation issue where errors thrown within Suspense boundaries after page render are not being captured in OTEL spans. The issue is timing-related: errors before render are captured, but errors after render are not. This suggests the span context is being lost or closed prematurely when Suspense boundaries resolve asynchronously.

Changes Made

  • modify: packages/next/src/server/lib/trace/tracer.ts
  • modify: packages/next/src/server/app-render/app-render.tsx
  • modify: packages/next/src/client/components/error-boundary.tsx
  • modify: packages/next/src/server/lib/trace/constants.ts

AI Model Used

claude-sonnet-4-5-20250929

Confidence Score

72%


This PR was automatically generated by Kodin

Changed files

  • packages/next/src/client/components/error-boundary.tsx (modified, +49/-20)
  • packages/next/src/server/app-render/app-render.tsx (modified, +1222/-782)
  • packages/next/src/server/lib/trace/constants.ts (modified, +0/-170)
  • packages/next/src/server/lib/trace/tracer.ts (modified, +399/-61)

PR #86596: Fix: Unhandled errors within a Suspense aren't appearing consistently in OTEL traces/spans

Description (problem / solution / changelog)

Fixes #86517

The root cause is likely in Next.js's instrumentation layer where async Suspense boundaries don't properly maintain span context for delayed errors. We need to modify the instrumentation to ensure error handlers remain attached to the active span context even after the initial render completes. This involves extending span lifecycle management for Suspense boundaries and ensuring error events are properly propagated to parent spans when caught by error boundaries within Suspense.

AI Analysis

This is an OpenTelemetry instrumentation issue where errors thrown within Suspense boundaries after page render are not being captured in OTEL spans. The issue is timing-related: errors before render are captured, but errors after render are not. This suggests the span context is being lost or closed prematurely when Suspense boundaries resolve asynchronously.

Changes Made

  • modify: packages/next/src/server/lib/trace/tracer.ts
  • modify: packages/next/src/server/app-render/app-render.tsx
  • modify: packages/next/src/client/components/error-boundary.tsx
  • modify: packages/next/src/server/lib/trace/constants.ts

AI Model Used

claude-sonnet-4-5-20250929

Confidence Score

72%


This PR was automatically generated by Kodin

Changed files

  • packages/next/src/client/components/error-boundary.tsx (modified, +49/-20)
  • packages/next/src/server/app-render/app-render.tsx (modified, +1222/-782)
  • packages/next/src/server/lib/trace/constants.ts (modified, +0/-170)
  • packages/next/src/server/lib/trace/tracer.ts (modified, +399/-61)

PR #86955: fix: otel error spans from streamed responses

Description (problem / solution / changelog)

When an error is thrown inside a Suspense boundary during streaming SSR, the error was not being captured in the "render route (app)" span. This happened because getTracer().wrap() ends the span as soon as the stream is created and returned, but errors inside Suspense boundaries occur asynchronously during stream consumption.

This PR changes the span management from using wrap() to manually calling startSpan() and tracking the span lifecycle. The span now stays open until allReady resolves or rejects. A new withSpan() helper was added to the tracer to properly activate the span context so child spans are parented. Error handlers now accept an optional spanToRecordOn parameter to record exceptions on the correct span rather than relying solely on the active scope span.

Fixes #86517

Changed files

  • packages/next/src/server/app-render/app-render.tsx (modified, +515/-455)
  • packages/next/src/server/app-render/create-error-handler.tsx (modified, +19/-16)
  • packages/next/src/server/lib/trace/tracer.ts (modified, +11/-0)
  • test/e2e/opentelemetry/instrumentation/app/app/[param]/loading/error/page.tsx (added, +8/-0)
  • test/e2e/opentelemetry/instrumentation/opentelemetry.test.ts (modified, +123/-0)

Code Example

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0
Binaries:
  Node: 22.9.0
  npm: 10.8.3
  pnpm: 10.17.0
Relevant Packages:
  next: 16.0.4
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/socsieng/nextjs-otel-repro

To Reproduce

  1. Start the development server.
  2. Trigger the error by interacting with the app: http://localhost:3000
    1. Click on the Expected tracing behaviour (with span error) link to see the expected behavior where the span records the error: http://localhost:3000/expected
    2. Click on the Unexpected tracing behaviour (without span error) link to see the unexpected behavior where the span does not record the error: http://localhost:3000/not-expected
    3. [optional] Click on the Expected tracing behaviour without suspense (with span error) link to see the expected behavior without Suspense where the span records the error: http://localhost:3000/no-suspense
  3. Observe the tracing behavior in the OpenTelemetry UI: http://localhost:8888/traces

Current vs. Expected behavior

Expected, with error event:

<img width="1362" height="2130" alt="Image" src="https://github.com/user-attachments/assets/e402f5fd-66f0-4049-97f9-91d98346cd13" />

Actual, without error event:

<img width="1362" height="2130" alt="Image" src="https://github.com/user-attachments/assets/c3fd59b6-7b07-4afd-ae4a-589e7031712b" />

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0
Binaries:
  Node: 22.9.0
  npm: 10.8.3
  pnpm: 10.17.0
Relevant Packages:
  next: 16.0.4
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Instrumentation

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

The issue appears to be related to timing of events within the suspense boundary and outside.

If the error in the suspense boundary occurs before the page has been rendered, then the span is attributed with the error event as expected. If the error occurs after the page has been rendered, then the span isn't attributed with the error event.

extent analysis

TL;DR

  • The issue can be mitigated by ensuring that error events are properly attributed to spans, potentially by adjusting the timing of events within the suspense boundary.

Guidance

  • Investigate the timing of error events in relation to the suspense boundary and page rendering to understand why the span is not being attributed with the error event when the error occurs after page rendering.
  • Review the OpenTelemetry instrumentation configuration to ensure that it is correctly set up to capture error events within the suspense boundary.
  • Consider adding logging or debugging statements to track the order of events and identify potential issues with the timing of error event attribution.
  • Experiment with adjusting the code to ensure that error events are properly attributed to spans, potentially by using a different approach to handling errors within the suspense boundary.

Example

Notes

  • The issue appears to be related to the timing of events within the suspense boundary and outside, and further investigation is needed to determine the root cause.
  • The provided environment information and code repository may be helpful in debugging the issue.

Recommendation

  • Apply workaround: Adjust the code to ensure that error events are properly attributed to spans, potentially by using a different approach to handling errors within the suspense boundary, as the root cause of the issue is not immediately clear and may require further investigation.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix Unhandled errors within a Suspense aren't appearing consistently in OTEL traces/spans [3 pull requests, 1 comments, 2 participants]