[FEATURE] Emit a source map from the server bundle so deployed worker.js stack traces can be remapped #1352
Description
Problem
The server bundling step calls esbuild without a sourcemap option, so .open-next/worker.js ships with no accompanying .map.
In v1.20.2, dist/cli/build/bundle-server.js sets bundle, outfile, format, target, minifyWhitespace, minifyIdentifiers, minifySyntax, legalComments, metafile, conditions and plugins — but nothing for sourcemap. grep -rni "sourcemap" across the whole installed package returns zero hits, and CloudflareOverrides / the cloudflare config block expose no escape hatch to enable it.
That severs the mapping chain for any error-reporting setup:
TS source -> next build (minified, .next/*.map produced)
-> opennextjs-cloudflare esbuild <-- no map emitted, chain breaks here
-> wrangler esbuild -> deployed worker.js
Because nothing maps .open-next/worker.js positions back to .next/server/*, downstream tooling cannot recover original frames no matter how it is configured:
- Sentry —
withSentryConfiguploads maps for the Next build only. Runtime frames arrive as bare offsets (worker.js:49444:191 (as)). The usualsentry-cli sourcemaps inject+wrangler deploy --no-bundlerecipe does not help, because the map it injects describes the wrangler pass only. - Cloudflare's own
upload_source_maps: true— produces a map for the final wrangler bundle whose sources resolve to the already-bundled OpenNext output, not to app source.
Possibly the underlying cause of the downstream report in getsentry/sentry-javascript#19213 (Next.js + OpenNext + Workers: source maps upload with valid Debug IDs, yet runtime frames still fail to resolve; currently labelled State: Blocked / External Dependency).
Request
Emit a source map from the server bundling pass — ideally opt-in via a build flag or an open-next.config.ts option, chaining from the Next build's own maps where available so the result maps back to original sources rather than to .next/server/* intermediates.
Even an unchained map (final bundle → .next/server/*) would be a meaningful improvement, since it could then be composed with the maps Next already produces.
Environment
@opennextjs/cloudflare1.20.2next16.2.12@sentry/nextjs10.63.0
Happy to open a PR if you'd like this behind a flag — just let me know your preference on opt-in vs. default and on chaining.
Activity
FriendlyCityJohnstown commentedon Sep 14, 2026
Measured cost of the
OPEN_NEXT_DEBUGworkaround — and why it is not a build-only switchSharing a measurement in case it helps prioritise this. Next 16.3.4,
@opennextjs/cloudflare1.20.6,@opennextjs/aws4.1.4. Two builds of the same commit, same machine, back to back — one default, one withOPEN_NEXT_DEBUG=true:OPEN_NEXT_DEBUG=trueworker.jsworker.js.maplib/**sources in the map.next/server/**wrangler deploy --dry-runIt works — the composed map starts carrying real application modules instead of only
.open-next/**,unenvand node polyfills. The shipped-size cost is also small: +2.0% gzip, because theminifycoupling inflates the intermediate.open-nextartifacts while the bundle that actually ships (wrangler's own esbuild pass) grows only 5.6% uncompressed.The problem is that the flag is not build-only.
globalThis.openNextDebugis read at runtime:adapters/logger.js:3debug(...)becomes a realconsole.logcore/routing/util.js:253-258X-OpenNext-VersionandX-OpenNext-RequestIdto responsesadapters/middleware.js:79So on Cloudflare Workers, getting a sourcemap for the server bundle currently also means switching production into debug logging and two extra response headers.
The ask: let
minifyandsourcemapbe set independently ofdebug. In@opennextjs/aws,build/helper.jsbinds all three together:(That binding comes from #629, "feat(debug): never minify in debug mode".) A dedicated env var — or simply honouring an explicit
sourcemap/minifyoption — would let a minified bundle ship with a map attached and no debug side effects. Emitting the map as a sibling.maprather than inline would additionally avoid embedding anything in the uploaded script.Related: #824 (specifically
handler.mjs), #1124.I have a reproducible local setup for the byte-for-byte comparison above and am happy to re-run it against a branch if that would help.