Fix: Sentry Not Working — Errors Not Captured, Source Maps Missing, or Performance Traces Empty
Quick Answer
How to fix Sentry issues — SDK initialization, source map uploads, error boundaries, performance monitoring, Next.js integration, release tracking, and alert configuration.
The Problem
Errors throw in your app but nothing appears in Sentry:
throw new Error('Something went wrong');
// Error fires but Sentry dashboard shows zero eventsOr errors appear but stack traces show minified code:
TypeError: Cannot read properties of undefined
at e.render (main.abc123.js:1:45678)
at t.processChild (main.abc123.js:1:12345)Or performance monitoring is enabled but no traces appear:
Sentry.init({
tracesSampleRate: 1.0,
});
// Zero transactions in the Performance tabWhy This Happens
Sentry captures errors and performance data through its SDK, which must be correctly initialized and configured:
Sentry.init()must run before any errors occur — the SDK intercepts uncaught exceptions and unhandled promise rejections. If initialization happens after the first error, that error is lost. In Next.js, the SDK must be initialized in multiple places (client, server, edge).- Source maps must be uploaded to Sentry — production builds are minified. Without source maps, Sentry can’t map minified code back to your original source. Source maps must be uploaded during the build process, not at runtime.
- The DSN must be correct — the Data Source Name tells the SDK where to send events. A wrong DSN silently drops all events. The DSN is project-specific and found in Sentry’s project settings.
- Sample rates control what’s captured —
tracesSampleRate: 0means no performance traces are collected. In production, you typically sample a percentage (e.g.,0.1for 10%) to reduce costs.
Fix 1: Next.js Integration
npx @sentry/wizard@latest -i nextjs
# Or manually:
npm install @sentry/nextjs// sentry.client.config.ts — client-side SDK
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NODE_ENV,
// Performance monitoring
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
// Session replay (optional)
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
integrations: [
Sentry.replayIntegration(),
Sentry.browserTracingIntegration(),
],
// Filter noisy errors
ignoreErrors: [
'ResizeObserver loop',
'Non-Error promise rejection',
/Loading chunk \d+ failed/,
],
// Before sending — sanitize sensitive data
beforeSend(event) {
if (event.request?.cookies) {
delete event.request.cookies;
}
return event;
},
});// sentry.server.config.ts — server-side SDK
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
});// sentry.edge.config.ts — edge runtime SDK
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.1,
});// next.config.mjs — wrap with Sentry
import { withSentryConfig } from '@sentry/nextjs';
const nextConfig = {};
export default withSentryConfig(nextConfig, {
org: 'my-org',
project: 'my-project',
authToken: process.env.SENTRY_AUTH_TOKEN,
// Upload source maps
sourcemaps: {
deleteSourcemapsAfterUpload: true, // Don't expose source maps publicly
},
// Automatically instrument API routes
autoInstrumentServerFunctions: true,
autoInstrumentMiddleware: true,
autoInstrumentAppRouter: true,
// Hide source maps from the client
hideSourceMaps: true,
// Silence warnings during build
silent: !process.env.CI,
});Fix 2: Manual Error Capture
// Capture exceptions explicitly
import * as Sentry from '@sentry/nextjs';
async function fetchData() {
try {
const res = await fetch('/api/data');
if (!res.ok) throw new Error(`API error: ${res.status}`);
return res.json();
} catch (error) {
// Capture with additional context
Sentry.captureException(error, {
tags: { section: 'data-fetch' },
extra: { url: '/api/data' },
level: 'error',
});
throw error;
}
}
// Capture messages (non-error events)
Sentry.captureMessage('User reached rate limit', {
level: 'warning',
tags: { userId: 'user-123' },
});
// Set user context — appears on all subsequent events
Sentry.setUser({
id: user.id,
email: user.email,
username: user.name,
});
// Clear on logout
Sentry.setUser(null);
// Add breadcrumbs — trail of events leading to an error
Sentry.addBreadcrumb({
category: 'navigation',
message: 'User navigated to /dashboard',
level: 'info',
});
Sentry.addBreadcrumb({
category: 'api',
message: 'Fetched user profile',
data: { userId: '123', status: 200 },
level: 'info',
});Fix 3: React Error Boundary
// app/global-error.tsx — Next.js App Router global error boundary
'use client';
import * as Sentry from '@sentry/nextjs';
import { useEffect } from 'react';
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
Sentry.captureException(error);
}, [error]);
return (
<html>
<body>
<div style={{ padding: '2rem', textAlign: 'center' }}>
<h2>Something went wrong!</h2>
<p>Our team has been notified.</p>
<button onClick={reset}>Try again</button>
</div>
</body>
</html>
);
}
// app/dashboard/error.tsx — route-specific error boundary
'use client';
import * as Sentry from '@sentry/nextjs';
import { useEffect } from 'react';
export default function DashboardError({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
useEffect(() => {
Sentry.captureException(error, {
tags: { page: 'dashboard' },
});
}, [error]);
return (
<div>
<h2>Dashboard Error</h2>
<p>{error.message}</p>
<button onClick={reset}>Retry</button>
</div>
);
}Fix 4: Source Map Configuration
# .env
SENTRY_AUTH_TOKEN=sntrys_xxxxxxxx # From Settings → Auth Tokens
SENTRY_ORG=my-org
SENTRY_PROJECT=my-nextjs-app
NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/zzz// For non-Next.js projects — upload source maps manually
// Install: npm install -D @sentry/cli
// .sentryclirc
[auth]
token=sntrys_xxxxxxxx
[defaults]
org=my-org
project=my-project# Upload source maps after build
npx sentry-cli sourcemaps upload \
--release=1.0.0 \
--url-prefix='~/' \
./dist
# Or in package.json
# "postbuild": "sentry-cli sourcemaps upload --release=$(git rev-parse HEAD) ./dist"Fix 5: Performance Monitoring
// Custom transactions
import * as Sentry from '@sentry/nextjs';
async function processOrder(orderId: string) {
return Sentry.startSpan(
{ name: 'process-order', op: 'task' },
async (span) => {
// Child spans for sub-operations
const order = await Sentry.startSpan(
{ name: 'fetch-order', op: 'db.query' },
() => db.query.orders.findFirst({ where: eq(orders.id, orderId) }),
);
await Sentry.startSpan(
{ name: 'charge-payment', op: 'http.client' },
() => chargePayment(order),
);
await Sentry.startSpan(
{ name: 'send-email', op: 'http.client' },
() => sendConfirmation(order),
);
span.setAttributes({ orderId, total: order.total });
return order;
},
);
}
// API route instrumentation — automatic with withSentryConfig
// app/api/users/route.ts
export async function GET() {
// Sentry automatically traces this route
const users = await db.query.users.findMany();
return Response.json(users);
}Fix 6: Alerts and Issue Management
// Sentry.init — configure which errors trigger alerts
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Attach release version for tracking
release: process.env.NEXT_PUBLIC_SENTRY_RELEASE || 'development',
// Environment for filtering
environment: process.env.NODE_ENV,
// Before sending — filter or modify events
beforeSend(event, hint) {
const error = hint.originalException;
// Ignore specific errors
if (error instanceof TypeError && error.message.includes('cancelled')) {
return null; // Don't send this event
}
// Add custom fingerprint for grouping
if (error instanceof ApiError) {
event.fingerprint = ['api-error', error.endpoint, String(error.status)];
}
return event;
},
// Before sending breadcrumbs — filter sensitive data
beforeBreadcrumb(breadcrumb) {
if (breadcrumb.category === 'xhr' && breadcrumb.data?.url?.includes('/api/auth')) {
breadcrumb.data = { ...breadcrumb.data, body: '[REDACTED]' };
}
return breadcrumb;
},
});Still Not Working?
Zero events in Sentry — check the DSN is correct in NEXT_PUBLIC_SENTRY_DSN. Open browser DevTools → Network and filter for sentry or ingest — you should see outgoing requests when errors occur. If requests appear but return 4xx, the DSN is wrong or the project is disabled.
Events captured but stack traces are minified — source maps aren’t uploaded. Verify SENTRY_AUTH_TOKEN is set during build (not just at runtime). Check the Sentry dashboard → Settings → Source Maps to see if maps were uploaded for the current release. The release in Sentry.init() must match the release used during upload.
Performance tab is empty — tracesSampleRate might be 0. Set it to 1.0 in development to capture all traces. Also check that browserTracingIntegration() is in the integrations array for client-side tracing.
Too many events / hitting quota — use beforeSend to filter noisy errors, ignoreErrors for known non-actionable errors, and lower tracesSampleRate in production. Set sampleRate: 0.5 to send only 50% of error events (not recommended for critical apps).
For related monitoring issues, see Fix: OpenTelemetry Not Working and Fix: Next.js App Router Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Deno PermissionDenied — Missing --allow-read, --allow-net, and Other Flags
How to fix Deno PermissionDenied (NotCapable in Deno 2) errors — the right permission flags, path-scoped permissions, deno.json permission sets, and the Deno.permissions API.
Fix: Fastify Not Working — 404, Plugin Encapsulation, and Schema Validation Errors
How to fix Fastify issues — route 404 from plugin encapsulation, reply already sent, FST_ERR_VALIDATION, request.body undefined, @fastify/cors, hooks not running, and TypeScript type inference.
Fix: Vinxi Not Working — Dev Server Not Starting, Routes Not Matching, or Build Failing
How to fix Vinxi server framework issues — app configuration, routers, server functions, middleware, static assets, and deployment to different platforms.
Fix: Clack Not Working — Prompts Not Displaying, Spinners Stuck, or Cancel Not Handled
How to fix @clack/prompts issues — interactive CLI prompts, spinners, multi-select, confirm dialogs, grouped tasks, cancellation handling, and building CLI tools with beautiful output.