The error arrives. You open it, and the stack trace looks like this:
TypeError: Cannot read properties of undefined (reading 'id')
at t (/_next/static/chunks/4823-a91e2f.js:1:48210)
at n (/_next/static/chunks/4823-a91e2f.js:1:52117)
at o (/_next/static/chunks/main-app-7b2c1d.js:1:9932)
Three single-letter functions and a column number in a one-line file. It is technically the truth and completely useless.
Sentry can un-minify this, but only if the build uploaded the source maps and tagged them with the same release identifier the running code reports. When one of those two halves is missing, you get exactly the output above, with no error, no warning, and a green build.
What has to line up
next buildgenerates source maps for client and server bundles.- The build uploads them to Sentry, tagged with a release name.
- The running app reports the same release name in every event.
- The maps are deleted from the deployed output, so nobody can read your
source by visiting
/_next/static/chunks/4823-a91e2f.js.map.
withSentryConfig does 1, 2 and 4. Step 3 is on you, and it is the one that
silently breaks.
The configuration
// next.config.ts
import { withSentryConfig } from "@sentry/nextjs/config"; // Sentry 11+
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// your config
};
export default withSentryConfig(nextConfig, {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
silent: !process.env.CI,
tunnelRoute: "/monitoring",
sourcemaps: { deleteSourcemapsAfterUpload: true },
});
And the release, set identically everywhere the SDK is initialised:
// sentry.server.config.ts and sentry.edge.config.ts
release: process.env.VERCEL_GIT_COMMIT_SHA,
// src/instrumentation-client.ts: note the NEXT_PUBLIC_ prefix
release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
Vercel exposes both automatically; you do not set them yourself. The client one
needs the NEXT_PUBLIC_ prefix because it has to be inlined into the browser
bundle at build time.
The five things that are actually wrong
1. SENTRY_AUTH_TOKEN is not set in the build environment
The most common cause by a distance. The plugin cannot upload without a token, and it does not fail the build when the token is missing: it logs a line you did not read and carries on.
Set it in Vercel > Settings > Environment Variables, for Production and
Preview. .env.local is not enough: it is not in the repository, so the
Vercel build never sees it.
The token needs project:releases scope. Create it under Sentry Settings >
Auth Tokens, and treat it as a write credential for your whole organisation,
because that is what it is.
2. Preview deployments were forgotten
A very common shape: production traces are readable, preview traces are not. Environment variables in Vercel are scoped per environment, and someone ticked only Production. Every preview then builds without a token.
Tick Preview as well. If you use it, tick Development too.
3. The release names do not match
The build uploads maps under one name and the running app reports another, so Sentry has maps and events that never meet. Symptoms: the release exists in Sentry with artifacts attached, but issues show minified frames.
Check the issue's Tags > release and compare it with the release listed under Sentry's Releases page. They must be byte-identical. Two ways this breaks:
- The client uses
VERCEL_GIT_COMMIT_SHA(undefined in the browser) instead ofNEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA. - Someone hardcoded
release: "1.0.0"in one config and left the others on the commit SHA.
4. Server-side traces are minified but client ones are fine
Next.js does not emit server source maps in production by default. The Sentry
plugin turns them on for you; if you have an explicit
productionBrowserSourceMaps or a custom webpack config that overrides
devtool, you can end up with client maps only. Remove the override and let
the plugin manage it.
5. The maps uploaded, but to the wrong project
SENTRY_ORG and SENTRY_PROJECT point at project A, the DSN points at project
B. Everything succeeds and nothing lines up. Compare the DSN's project id with
the project slug in your environment variables.
Verifying, without waiting for a real error
Make the build noisy first:
SENTRY_AUTH_TOKEN=... SENTRY_ORG=... SENTRY_PROJECT=... bun run build
With silent: false you should see the plugin resolve your org and project,
create a release, and upload a number of artifacts. Zero artifacts means the
upload did not happen; read the line above it.
Then check in Sentry: Releases > your commit SHA > Artifacts. If files are listed there and issues are still minified, the problem is release-name mismatch (cause 3), not upload.
Finally, deploy a throwaway route that throws, hit it, and confirm the issue shows a real file path and line number. Delete the route.
Do not commit the token
SENTRY_AUTH_TOKEN is a build-time secret with write access to your Sentry
organisation. It must never appear in next.config.ts as a literal, never be
prefixed NEXT_PUBLIC_, and never be read by application code. It belongs in
Vercel's environment variables and in your local .env.local, which is
gitignored. If it ever lands in a commit, revoke it in Sentry immediately:
rotating is thirty seconds and there is no reason to hesitate.