Skip to content

Next.js/Turbopack: client source maps silently not uploaded (and deleted anyway) when Next emits chunks to static/immutable/ (supportsImmutableAssets, auto-enabled on Vercel) #21962

Description

@greyscm

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nextjs

SDK Version

10.53.1

Framework Version

Next.js 16.3.0-preview.3 (Turbopack build)

Link to Sentry event

N/A (build-time source map upload issue)

Reproduction Example/SDK Setup

Minimal Next.js app wrapped with withSentryConfig:

// next.config.mjs
import { withSentryConfig } from '@sentry/nextjs'

export default withSentryConfig(
  {
    productionBrowserSourceMaps: true,
    // Vercel's builder enables this automatically on Next 16 preview builds —
    // user code setting it to `false` is overridden by the platform.
    experimental: { supportsImmutableAssets: true },
  },
  {
    org: '...',
    project: '...',
    sourcemaps: { deleteSourcemapsAfterUpload: true },
  }
)

Steps to Reproduce

  1. SENTRY_AUTH_TOKEN=... next build (Turbopack).
  2. With experimental.supportsImmutableAssets enabled, Turbopack emits client chunks to .next/static/immutable/chunks/ instead of .next/static/chunks/ — this is what Vercel production builds do on Next 16 preview: the builder forces the flag on, and setting it to false in next.config is overridden by the platform.
  3. Watch the After Production Compile upload output.

Building the same app with and without the flag isolates it: without the flag the client phase uploads normally (7 files in a create-next-app-sized repro, ~150 in our real app); with it, the client phase logs > Nothing to upload and zero .map files remain on disk.

Expected Result

Client source maps are uploaded wherever Next emits them, and deleteSourcemapsAfterUpload only deletes maps that were actually uploaded.

Actual Result

Two composing bugs in packages/nextjs/src/config/getBuildPluginOptions.ts:

  1. The upload misses the immutable layout. The Turbopack client upload pattern is hardcoded to static/chunks:
STATIC_CHUNKS: { GLOB: 'static/chunks/**', PATH: 'static/chunks' }

so with the immutable layout the client phase logs > Nothing to upload, while the server phase (.next/server) uploads fine (Bundled 1264 files for upload).

  1. The deletion still catches them. deleteSourcemapsAfterUpload uses a broader glob:
return SOURCEMAP_EXTENSIONS.map(ext => path.posix.join(normalizedDistPath, 'static', '**', ext));

so the client .map files are deleted without ever having been uploaded.

The net effect is completely silent: the build succeeds, server maps upload, and every browser stack trace arrives minified. Since Vercel's builder auto-enables supportsImmutableAssets on Next 16 preview, this affects Vercel deployments without any user action or signal.

Workaround (verified — client phase goes from Nothing to upload to 153 files uploaded, and stack traces symbolicate in Sentry):

sourcemaps: {
  assets: ['.next/server', '.next/static'], // covers both static/chunks and static/immutable/chunks
  deleteSourcemapsAfterUpload: true,
}

Suggested fix: include static/immutable/chunks (or derive the pattern from the build output) in the Turbopack client upload patterns — and, independently, never let the deletion glob be broader than the upload glob.

Metadata

Metadata

Assignees

No one assigned

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Waiting for: Product Owner

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions