diff --git a/sentry-javascript/19367/README.md b/sentry-javascript/19367/README.md
new file mode 100644
index 0000000..d114d14
--- /dev/null
+++ b/sentry-javascript/19367/README.md
@@ -0,0 +1,97 @@
+# Reproduction for sentry-javascript#19367
+
+**Issue:** https://github.com/getsentry/sentry-javascript/issues/19367
+
+## Description
+
+Next.js 16 with Turbopack (the default bundler) splits `@opentelemetry/api` across
+multiple server-side chunks instead of deduplicating it into a single module instance.
+When two chunks each contain their own copy of the OTel `ContextAPI`, the `.with()`
+method of each copy delegates to the _other_ copy's `.with()`, creating infinite mutual
+recursion that fatally crashes the Node.js process with:
+
+```
+RangeError: Maximum call stack size exceeded
+```
+
+This reproduces with `@sentry/nextjs` 10.38.0 + Next.js 16.1.6 Turbopack and does **not**
+reproduce on `@sentry/nextjs` 10.8.0.
+
+## Steps to Reproduce
+
+1. Install dependencies:
+ ```bash
+ npm install
+ ```
+
+2. (Optional) Export your Sentry DSN – the app works without one, but events won't be sent:
+ ```bash
+ export SENTRY_DSN=https://your-key@oXXXXXX.ingest.sentry.io/XXXXXX
+ ```
+
+3. Build with Turbopack (the default for Next.js 16):
+ ```bash
+ npm run build
+ ```
+
+4. **Detect the duplicate OTel chunks immediately after the build:**
+ ```bash
+ npm run check-otel-dedup
+ ```
+ Expected output shows `@opentelemetry/api` duplicated across 7 server-side chunks.
+
+5. Start the production server:
+ ```bash
+ npm start
+ ```
+
+6. Send requests to trigger OTel context propagation:
+ ```bash
+ # Single request
+ curl http://localhost:3000/api/test
+
+ # Load test – the crash is intermittent; sustained traffic triggers it
+ for i in $(seq 1 500); do curl -s http://localhost:3000/api/test > /dev/null; done
+ ```
+
+The server may crash with `RangeError: Maximum call stack size exceeded` during or after
+the load test. The crash is non-deterministic – it can happen within minutes or after
+several hours of traffic (matching the original report).
+
+## Expected Behavior
+
+`@opentelemetry/api` is loaded as a single module instance. The `.with()` context method
+works without recursion and the server remains stable.
+
+## Actual Behavior
+
+`npm run check-otel-dedup` reports:
+
+```
+✗ BUG DETECTED: @opentelemetry/api module definition found in 7 chunks:
+ - [root-of-the-server]__14b38a08._.js
+ - [root-of-the-server]__1a01c8dc._.js
+ - [root-of-the-server]__6126aa9f._.js
+ - [root-of-the-server]__ab5f2c12._.js
+ - [root-of-the-server]__da904e4a._.js
+ - [root-of-the-server]__f934a92d._.js
+ - node_modules_@opentelemetry_a01cbabd._.js
+```
+
+Under sustained traffic the server crashes:
+
+```
+RangeError: Maximum call stack size exceeded
+ at ContextAPI.with (.next/server/chunks/[root-of-the-server]__14b38a08._.js:...)
+ at ContextAPI.with (.next/server/chunks/node_modules_@opentelemetry_a01cbabd._.js:...)
+ at ContextAPI.with (.next/server/chunks/[root-of-the-server]__14b38a08._.js:...)
+ ...
+```
+
+## Environment
+
+- Node.js: v24.12.0 (also reproduces on v22)
+- `@sentry/nextjs`: 10.38.0
+- `next`: 16.1.6 (Turbopack)
+- `@prisma/instrumentation`: ^7.4.0
+- OS: Linux (Debian 12) / macOS (development)
diff --git a/sentry-javascript/19367/app/api/test/route.ts b/sentry-javascript/19367/app/api/test/route.ts
new file mode 100644
index 0000000..e761b18
--- /dev/null
+++ b/sentry-javascript/19367/app/api/test/route.ts
@@ -0,0 +1,18 @@
+import { NextResponse } from "next/server";
+
+// This route triggers OTel context propagation on every request.
+// With @sentry/nextjs 10.38.0 + Next.js 16 Turbopack, @opentelemetry/api ends up
+// bundled in two separate chunks. Each chunk's ContextAPI.with() delegates to the
+// other copy's with(), creating infinite mutual recursion →
+// RangeError: Maximum call stack size exceeded
+export async function GET() {
+ // Simulate a minimal workload so Sentry/OTel creates spans
+ const start = Date.now();
+ await new Promise((resolve) => setTimeout(resolve, 1));
+
+ return NextResponse.json({
+ status: "ok",
+ timestamp: Date.now(),
+ duration: Date.now() - start,
+ });
+}
diff --git a/sentry-javascript/19367/app/layout.tsx b/sentry-javascript/19367/app/layout.tsx
new file mode 100644
index 0000000..225b603
--- /dev/null
+++ b/sentry-javascript/19367/app/layout.tsx
@@ -0,0 +1,11 @@
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
{children}
+
+ );
+}
diff --git a/sentry-javascript/19367/app/page.tsx b/sentry-javascript/19367/app/page.tsx
new file mode 100644
index 0000000..39018c4
--- /dev/null
+++ b/sentry-javascript/19367/app/page.tsx
@@ -0,0 +1,20 @@
+export default function Home() {
+ return (
+
+ Repro: sentry-javascript#19367
+
+ Next.js 16 + Turbopack duplicates @opentelemetry/api across
+ chunks, causing infinite .with() recursion.
+
+
+ Hit the /api/test endpoint repeatedly (or under
+ load) to trigger OTel context propagation. The server may crash with{" "}
+ RangeError: Maximum call stack size exceeded.
+
+
+ Run npm run check-otel-dedup after building to detect
+ duplicate @opentelemetry/api chunks in the output.
+
+
+ );
+}
diff --git a/sentry-javascript/19367/instrumentation.ts b/sentry-javascript/19367/instrumentation.ts
new file mode 100644
index 0000000..f8a929b
--- /dev/null
+++ b/sentry-javascript/19367/instrumentation.ts
@@ -0,0 +1,9 @@
+export async function register() {
+ if (process.env.NEXT_RUNTIME === "nodejs") {
+ await import("./sentry.server.config");
+ }
+
+ if (process.env.NEXT_RUNTIME === "edge") {
+ await import("./sentry.edge.config");
+ }
+}
diff --git a/sentry-javascript/19367/next.config.js b/sentry-javascript/19367/next.config.js
new file mode 100644
index 0000000..cd850cd
--- /dev/null
+++ b/sentry-javascript/19367/next.config.js
@@ -0,0 +1,17 @@
+const { withSentryConfig } = require("@sentry/nextjs");
+
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ // Turbopack is the default in Next.js 16, no extra config needed
+};
+
+module.exports = withSentryConfig(nextConfig, {
+ org: "your-org",
+ project: "your-project",
+ // Suppress build output noise for the repro
+ silent: true,
+ // Disable source map upload since we have no real DSN
+ sourcemaps: {
+ disable: true,
+ },
+});
diff --git a/sentry-javascript/19367/package.json b/sentry-javascript/19367/package.json
new file mode 100644
index 0000000..cd1cbaf
--- /dev/null
+++ b/sentry-javascript/19367/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "repro-sentry-javascript-19367",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "dev": "next dev --turbopack",
+ "build": "next build",
+ "start": "next start",
+ "check-otel-dedup": "node scripts/check-otel-dedup.js"
+ },
+ "dependencies": {
+ "@prisma/instrumentation": "^7.4.0",
+ "@sentry/nextjs": "10.38.0",
+ "next": "16.1.6",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ },
+ "devDependencies": {
+ "@types/node": "^20",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "typescript": "^5"
+ }
+}
diff --git a/sentry-javascript/19367/scripts/check-otel-dedup.js b/sentry-javascript/19367/scripts/check-otel-dedup.js
new file mode 100644
index 0000000..963d4c5
--- /dev/null
+++ b/sentry-javascript/19367/scripts/check-otel-dedup.js
@@ -0,0 +1,62 @@
+#!/usr/bin/env node
+/**
+ * Checks the Next.js build output (.next/server/chunks/) for duplicate
+ * @opentelemetry/api module definitions, which is the root cause of the
+ * infinite .with() recursion described in sentry-javascript#19367.
+ *
+ * Run after `npm run build`:
+ * node scripts/check-otel-dedup.js
+ */
+
+const fs = require("fs");
+const path = require("path");
+
+const chunksDir = path.join(__dirname, "../.next/server/chunks");
+
+if (!fs.existsSync(chunksDir)) {
+ console.error(
+ "ERROR: .next/server/chunks not found. Run `npm run build` first."
+ );
+ process.exit(1);
+}
+
+const files = fs.readdirSync(chunksDir).filter((f) => f.endsWith(".js"));
+
+const otelChunks = [];
+
+for (const file of files) {
+ const content = fs.readFileSync(path.join(chunksDir, file), "utf8");
+ // @opentelemetry/api registers itself via a global symbol; look for the module definition
+ if (
+ content.includes("@opentelemetry/api") &&
+ (content.includes("ContextAPI") ||
+ content.includes("context._currentContext") ||
+ content.includes("Symbol.for(\"opentelemetry.js.api"))
+ ) {
+ otelChunks.push(file);
+ }
+}
+
+console.log(`\nScanned ${files.length} server chunks in ${chunksDir}\n`);
+
+if (otelChunks.length === 0) {
+ console.log("✓ No @opentelemetry/api module definitions found (may be externalized).");
+} else if (otelChunks.length === 1) {
+ console.log(
+ `✓ @opentelemetry/api appears in exactly 1 chunk: ${otelChunks[0]}`
+ );
+ console.log(" This is the expected (non-duplicated) state.");
+} else {
+ console.error(
+ `✗ BUG DETECTED: @opentelemetry/api module definition found in ${otelChunks.length} chunks:`
+ );
+ for (const f of otelChunks) {
+ console.error(` - ${f}`);
+ }
+ console.error(
+ "\n Two copies of @opentelemetry/api means their .with() methods will\n" +
+ " delegate to each other infinitely → RangeError: Maximum call stack\n" +
+ " size exceeded (sentry-javascript#19367)."
+ );
+ process.exit(1);
+}
diff --git a/sentry-javascript/19367/sentry.client.config.ts b/sentry-javascript/19367/sentry.client.config.ts
new file mode 100644
index 0000000..3e36b9b
--- /dev/null
+++ b/sentry-javascript/19367/sentry.client.config.ts
@@ -0,0 +1,6 @@
+import * as Sentry from "@sentry/nextjs";
+
+Sentry.init({
+ dsn: process.env.SENTRY_DSN || "",
+ tracesSampleRate: 1,
+});
diff --git a/sentry-javascript/19367/sentry.edge.config.ts b/sentry-javascript/19367/sentry.edge.config.ts
new file mode 100644
index 0000000..3e36b9b
--- /dev/null
+++ b/sentry-javascript/19367/sentry.edge.config.ts
@@ -0,0 +1,6 @@
+import * as Sentry from "@sentry/nextjs";
+
+Sentry.init({
+ dsn: process.env.SENTRY_DSN || "",
+ tracesSampleRate: 1,
+});
diff --git a/sentry-javascript/19367/sentry.server.config.ts b/sentry-javascript/19367/sentry.server.config.ts
new file mode 100644
index 0000000..f71354b
--- /dev/null
+++ b/sentry-javascript/19367/sentry.server.config.ts
@@ -0,0 +1,12 @@
+import * as Sentry from "@sentry/nextjs";
+
+Sentry.init({
+ dsn: process.env.SENTRY_DSN || "",
+ tracesSampleRate: 1,
+ integrations: [
+ // prismaIntegration triggers @prisma/instrumentation which registers OTel instrumentations.
+ // Combined with Turbopack's chunk splitting, this leads to two copies of @opentelemetry/api
+ // whose .with() methods recursively call each other → RangeError: Maximum call stack size exceeded.
+ Sentry.prismaIntegration(),
+ ],
+});
diff --git a/sentry-javascript/19367/tsconfig.json b/sentry-javascript/19367/tsconfig.json
new file mode 100644
index 0000000..e7ff3a2
--- /dev/null
+++ b/sentry-javascript/19367/tsconfig.json
@@ -0,0 +1,41 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ }
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}