Is there an existing issue for this?
How do you use Sentry?
Not relevant. The problem occurs with Sentry.init({}) and no DSN.
Which SDK are you using?
@sentry/nextjs
SDK Version
11.6.0 and 10.71.0. Both are affected. The stack and the two Sentry.init option rows below are from 10.71.0.
Framework Version
Next.js 16.3.8 with cacheComponents: true, on Cloudflare Workers (@opennextjs/cloudflare 1.20.10 and the build of opennextjs/opennextjs-cloudflare#1318, workerd 1.20261006.1, compatibility date 2025-09-15)
Link to Sentry event
No response
Reproduction Example/SDK Setup
https://github.com/kmsomebody/cache-components-repro
instrumentation.ts calls Sentry.init({}) for the nodejs runtime.
I changed these versions in the repository: next 16.3.8, @opennextjs/cloudflare 1.20.10, wrangler 4.149.0, @sentry/nextjs 11.6.0. For 11.6.0, next.config.ts imports withSentryConfig from @sentry/nextjs/config.
Steps to Reproduce
- Build the app with
opennextjs-cloudflare build and start it with opennextjs-cloudflare preview.
- Open
/ in a browser. The page prefetches /static and /dynamic.
- Look at the two prefetch requests that have the header
next-router-prefetch: 3.
Three requests in flight are necessary. Sequential requests are correct.
Expected Result
The responses are the same as with next start. The /static prefetch has 174538 bytes and the /dynamic prefetch has 1970 bytes.
Actual Result
The body of each prefetch is one byte, ~, which is the Next.js marker for a partial response. This occurs in 28 to 30 of 30 concurrent requests. With next start, it occurs in 0 of 30.
Additional Context
prepareSafeIdGeneratorContext keeps one AsyncLocalStorage.snapshot() for all requests. On workerd, a snapshot is bound to the request that made it. This is the default from compatibility date 2025-06-16. When a different request calls the snapshot, it throws. The wrapper then takes a new snapshot in the current context and stores it for all requests.
When requests overlap, a request finds a snapshot from a different request while it renders. It takes the new snapshot inside the Next.js prerender context, so the "safe" context is no longer outside the render. uuid4 then calls crypto.randomUUID() there, and Next.js stops the prerender. This is the stack, with the minified names replaced:
Route /static needs to bail out of prerendering at this point because it used `crypto.randomUUID()`.
at abortOnSynchronousPlatformIOAccess
at io
at webCrypto.randomUUID
at withRandomSafeContext
at uuid4
at generateTraceId
at new Scope
at Scope.clone
at buildContextWithSentryScopes
at SentryAsyncLocalStorageContextManager.with
at ContextAPI.with
at NextTracerImpl.trace
Results with 30 concurrent prefetch requests for each route:
| Change |
One-byte bodies |
None, Sentry.init({}) |
28 to 30 of 30 |
Sentry.init({ enabled: false }) |
29 to 30 of 30 |
Sentry.init({ skipOpenTelemetrySetup: true }) |
0 of 30 |
workerd flag do_not_bind_asynclocalstorage_snapshot_to-request |
0 of 30 |
The worker bundle contains the Node.js server build of the SDK, not the edge build.
#21510 was a different cause of the same Next.js error.
Is there an existing issue for this?
How do you use Sentry?
Not relevant. The problem occurs with
Sentry.init({})and no DSN.Which SDK are you using?
@sentry/nextjs
SDK Version
11.6.0 and 10.71.0. Both are affected. The stack and the two
Sentry.initoption rows below are from 10.71.0.Framework Version
Next.js 16.3.8 with
cacheComponents: true, on Cloudflare Workers (@opennextjs/cloudflare1.20.10 and the build of opennextjs/opennextjs-cloudflare#1318, workerd 1.20261006.1, compatibility date 2025-09-15)Link to Sentry event
No response
Reproduction Example/SDK Setup
https://github.com/kmsomebody/cache-components-repro
instrumentation.tscallsSentry.init({})for thenodejsruntime.I changed these versions in the repository:
next16.3.8,@opennextjs/cloudflare1.20.10,wrangler4.149.0,@sentry/nextjs11.6.0. For 11.6.0,next.config.tsimportswithSentryConfigfrom@sentry/nextjs/config.Steps to Reproduce
opennextjs-cloudflare buildand start it withopennextjs-cloudflare preview./in a browser. The page prefetches/staticand/dynamic.next-router-prefetch: 3.Three requests in flight are necessary. Sequential requests are correct.
Expected Result
The responses are the same as with
next start. The/staticprefetch has 174538 bytes and the/dynamicprefetch has 1970 bytes.Actual Result
The body of each prefetch is one byte,
~, which is the Next.js marker for a partial response. This occurs in 28 to 30 of 30 concurrent requests. Withnext start, it occurs in 0 of 30.Additional Context
prepareSafeIdGeneratorContextkeeps oneAsyncLocalStorage.snapshot()for all requests. On workerd, a snapshot is bound to the request that made it. This is the default from compatibility date 2025-06-16. When a different request calls the snapshot, it throws. The wrapper then takes a new snapshot in the current context and stores it for all requests.When requests overlap, a request finds a snapshot from a different request while it renders. It takes the new snapshot inside the Next.js prerender context, so the "safe" context is no longer outside the render.
uuid4then callscrypto.randomUUID()there, and Next.js stops the prerender. This is the stack, with the minified names replaced:Results with 30 concurrent prefetch requests for each route:
Sentry.init({})Sentry.init({ enabled: false })Sentry.init({ skipOpenTelemetrySetup: true })do_not_bind_asynclocalstorage_snapshot_to-requestThe worker bundle contains the Node.js server build of the SDK, not the edge build.
#21510 was a different cause of the same Next.js error.