Conversation
Reproduces: Next.js 16 + Turbopack duplicates @opentelemetry/api across server-side chunks, causing infinite .with() recursion and a fatal RangeError: Maximum call stack size exceeded. The check-otel-dedup script confirms 7 duplicate OTel chunks in the build output, matching the root cause described in the issue. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Merge all investigation findings into README.md, add diagnostic route (/api/otel-check), enhanced check-otel-dedup script that maps per-route chunk loading, force-crash.js for isolated testing, and realistic nested Sentry.startSpan() route. Add .next/ and next-env.d.ts to .gitignore. Key findings: Turbopack duplication is confirmed and deterministic but the actual RangeError crash could not be triggered locally -- likely requires Node.js v24, real Prisma queries, or sustained production traffic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| "instances instead of deduplicating into a single shared chunk."; | ||
|
|
||
| return NextResponse.json(diagnostics, { | ||
| status: contextWithResult.startsWith("CRASH") ? 500 : 200, |
There was a problem hiding this comment.
Status code ignores the nested crash test result
Medium Severity
The HTTP status code is determined solely by contextWithResult (the single context.with() test), but ignores nestedResult (the 3-deep nested test). The nested test is the one that mimics _startSpan()'s pattern from SDK 10.38.0 — the exact scenario that triggers the infinite recursion crash. If the simple test passes but the nested test crashes, the endpoint returns 200 instead of 500, making automated detection of the bug's primary failure mode impossible.
Additional Locations (1)
| * context.with() path the way @sentry/opentelemetry's _startSpan() does. | ||
| */ | ||
|
|
||
| const Module = require("module"); |
| const chunks = (content.match(/R\.c\("([^"]+)"\)/g) || []).map(m => m.match(/"([^"]+)"/)[1]); | ||
| const routeName = rf.replace(serverDir + "/app", "").replace(/\/(route|page)\.js$/, "") || "/"; | ||
| routes[routeName] = chunks; | ||
| } |
There was a problem hiding this comment.
Route chunks miss dynamic chunk refs, causing false negatives
Medium Severity
The instrumentation entry point analysis follows two levels of chunk references — it collects static R.c() refs and then scans those chunks for dynamic e.l() refs (lines 43–53). Route entry points only collect static R.c() refs (line 72) and never resolve dynamic chunk refs within those. This asymmetry means any @opentelemetry/api code loaded through a route's dynamic chunks is invisible to the duplication comparison, potentially producing false negatives in the diagnostic output.


Reproduces: Next.js 16 + Turbopack duplicates @opentelemetry/api across server-side chunks, causing infinite .with() recursion and a fatal RangeError: Maximum call stack size exceeded.
The check-otel-dedup script confirms 7 duplicate OTel chunks in the build output, matching the root cause described in the issue.