sentry-known-pitfallsClaude Skill
Execute common Sentry pitfalls and how to avoid them.
| name | sentry-known-pitfalls |
| description | Identify and fix common Sentry SDK pitfalls that cause silent data loss, cost overruns, and missed alerts. Covers 10 anti-patterns with fix code. Use when auditing Sentry config, debugging missing events, or reviewing SDK setup. Trigger: "sentry pitfalls", "sentry anti-patterns", "sentry mistakes", "why are sentry events missing". |
| allowed-tools | Read, Write, Edit, Grep, Glob, Bash(node:*), Bash(npm:*), Bash(npx:*), Bash(grep:*), Bash(find:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| compatible-with | claude-code, codex, openclaw |
| tags | ["saas","sentry","anti-patterns","troubleshooting","best-practices","sdk","configuration"] |
Sentry Known Pitfalls
Overview
Ten production-grade Sentry SDK anti-patterns that silently break error tracking, inflate costs, or leave teams blind to failures. Each pitfall includes the broken pattern, root cause, and production-ready fix.
For extended code samples and audit scripts, see configuration pitfalls, error capture pitfalls, SDK initialization pitfalls, integration pitfalls, and monitoring pitfalls.
Prerequisites
- Active Sentry project with
@sentry/node>= 8.x or@sentry/browser>= 8.x - Access to the codebase containing
Sentry.init()configuration - Environment variable management (
.env, secrets manager, or CI/CD vars)
Instructions
Step 1: Scan for Existing Pitfalls
# Hardcoded DSNs (Pitfall 1) grep -rn "ingest\.sentry\.io" --include="*.ts" --include="*.js" src/ # 100% sample rates (Pitfall 2) grep -rn "sampleRate.*1\.0" --include="*.ts" --include="*.js" src/ # Missing flush calls (Pitfall 3) grep -rn "Sentry\.flush\|Sentry\.close" --include="*.ts" --include="*.js" src/ # Wrong SDK imports (Pitfall 8) grep -rn "@sentry/node" --include="*.tsx" --include="*.jsx" src/
Step 2: Pitfall 1 — Hardcoding DSN in Source Code
DSN in source ships in client bundles and cannot be rotated without a deploy. Attackers flood your project with garbage events.
// WRONG Sentry.init({ dsn: 'https://abc123@o123456.ingest.us.sentry.io/7890123', }); // RIGHT — environment variable Sentry.init({ dsn: process.env.SENTRY_DSN }); // RIGHT — browser apps: build-time injection (Vite) // vite.config.ts: define: { __SENTRY_DSN__: JSON.stringify(process.env.SENTRY_DSN) } // app.ts: Sentry.init({ dsn: __SENTRY_DSN__ });
Step 3: Pitfall 2 — sampleRate: 1.0 in Production
100% sampling sends every trace. At 500K requests/day, overage is ~$371/month.
// WRONG Sentry.init({ tracesSampleRate: 1.0 }); // RIGHT — endpoint-specific sampling Sentry.init({ tracesSampler: ({ name, parentSampled }) => { if (typeof parentSampled === 'boolean') return parentSampled; if (name?.match(/\/(health|ping|ready)/)) return 0; if (name?.includes('/checkout')) return 0.25; return 0.01; // 1% default }, replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1.0, });
Step 4: Pitfall 3 — Not Calling flush() in Serverless/CLI
Sentry queues events in memory. Serverless/CLI processes exit before the queue drains — events never reach Sentry.
// WRONG — Lambda exits, events lost export const handler = async (event) => { try { return await processEvent(event); } catch (error) { Sentry.captureException(error); throw error; // Queue never drains } }; // RIGHT — flush before exit export const handler = async (event) => { try { return await processEvent(event); } catch (error) { Sentry.captureException(error); await Sentry.flush(2000); throw error; } }; // BEST — use @sentry/aws-serverless wrapper import * as Sentry from '@sentry/aws-serverless'; export const handler = Sentry.wrapHandler(async (event) => { return await processEvent(event); });
Step 5: Pitfall 4 — beforeSend Returning null for All Events
Missing return event causes JavaScript to return undefined, which Sentry treats as "drop." A single missing return kills all tracking.
// WRONG — non-error events silently vanish Sentry.init({ beforeSend(event) { if (event.level === 'error') return event; // Falls through — undefined — ALL non-errors dropped }, }); // RIGHT — always return event as the last line Sentry.init({ beforeSend(event, hint) { const error = hint?.originalException; if (error instanceof Error && error.message.match(/^NetworkError/)) { return null; // Explicit drop } return event; // Always the last line }, });
Step 6: Pitfall 5 — Release Version Mismatch (SDK vs Source Maps)
SDK release must exactly match sentry-cli releases new. A v prefix mismatch means source maps never apply.
// WRONG — "1.2.3" vs "v1.2.3" Sentry.init({ release: process.env.npm_package_version }); // CLI: sentry-cli releases new "v1.2.3" // RIGHT — single source of truth const SENTRY_RELEASE = `myapp@${process.env.GIT_SHA || 'dev'}`; Sentry.init({ release: SENTRY_RELEASE });
# CI — same variable feeds both SDK and CLI export SENTRY_RELEASE="myapp@$(git rev-parse --short HEAD)" npx sentry-cli releases new "$SENTRY_RELEASE" npx sentry-cli sourcemaps upload --release="$SENTRY_RELEASE" \ --url-prefix="~/static/js" ./dist/static/js/ npx sentry-cli releases finalize "$SENTRY_RELEASE"
Step 7: Pitfall 6 — Catching Errors Without Re-Throwing
Capturing to Sentry but not re-throwing means the function returns undefined. Downstream code breaks silently.
// WRONG — returns undefined async function getUser(id: string) { try { return await fetch(`/api/users/${id}`).then(r => r.json()); } catch (error) { Sentry.captureException(error); // Returns undefined — callers get TypeError } } // RIGHT — capture and re-throw async function getUser(id: string) { try { return await fetch(`/api/users/${id}`).then(r => r.json()); } catch (error) { Sentry.captureException(error); throw error; } }
Step 8: Pitfall 7 — Missing environment Tag
Without environment, dev errors pollute prod dashboards. Alert rules fire on local noise. Issue counts are inflated.
// WRONG Sentry.init({ dsn: process.env.SENTRY_DSN }); // RIGHT Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV || 'development', }); // For Vercel/Railway preview environments: function getSentryEnvironment(): string { if (process.env.VERCEL_ENV) return process.env.VERCEL_ENV; if (process.env.RAILWAY_ENVIRONMENT) return process.env.RAILWAY_ENVIRONMENT; return process.env.NODE_ENV || 'development'; }
Step 9: Pitfall 8 — Importing @sentry/node in Browser Bundle
@sentry/node depends on Node.js built-ins (http, fs). Browser import causes build failures, 100KB+ polyfill bloat, or runtime crashes.
// WRONG import * as Sentry from '@sentry/node'; // In React/Vue/browser code // RIGHT — platform-specific SDK import * as Sentry from '@sentry/react'; // React import * as Sentry from '@sentry/vue'; // Vue import * as Sentry from '@sentry/nextjs'; // Next.js (client + server) import * as Sentry from '@sentry/node'; // Server-only import * as Sentry from '@sentry/aws-serverless'; // AWS Lambda
Step 10: Pitfall 9 — Ignoring 429 Too Many Requests
When quota is exceeded, Sentry returns 429 and the SDK silently drops events. You lose data during peak traffic — exactly when you need it most.
Prevention:
- Enable Spike Protection in Sentry Organization Settings
- Set per-key rate limits in Project Settings > Client Keys
- Monitor client reports: Project Settings > Client Keys > Stats
// Client-side circuit breaker for resilience let sentryBackoff = 0; Sentry.init({ beforeSend(event) { if (Date.now() < sentryBackoff) return null; return event; }, });
Step 11: Pitfall 10 — No Alert Rules Configured
Sentry collects errors but does not notify anyone by default. Without alerts, critical bugs go unnoticed for hours.
Three-tier alert structure:
| Tier | Trigger | Channel |
|---|---|---|
| Immediate | New fatal/error issue in prod | PagerDuty |
| Urgent | Error rate > 100 events in 5 min | Slack #alerts |
| Awareness | Issue unresolved > 7 days | Email digest |
Set up in Sentry UI: Alerts > Create Alert > Issue Alert (Tier 1) or Metric Alert (Tier 2). See monitoring pitfalls for API-based alert creation.
Step 12: Run the Full Audit Checklist
See audit script for a bash script that checks all 10 pitfalls in one pass.
Output
- Audit report listing which of the 10 pitfalls were found
- Code changes applied for each identified pitfall
- Confirmation that
beforeSendreturnseventon all paths environmentandreleaseproperly configured- Alert rules created or recommended (three tiers)
Error Handling
| Pitfall | Symptom | Fix |
|---|---|---|
| Hardcoded DSN | Spam events from attackers | process.env.SENTRY_DSN or build-time injection |
sampleRate: 1.0 | 10-50x cost overrun | tracesSampler with per-endpoint rates |
No flush() | Zero events from Lambda/CLI | await Sentry.flush(2000) before exit |
beforeSend drops all | Events silently vanish | Always end with return event |
| Release mismatch | Minified stack traces | Single SENTRY_RELEASE env var |
| Swallowed catch | Cascading undefined errors | Re-throw after capture |
No environment | Dev noise in prod dashboard | environment: process.env.NODE_ENV |
| Wrong SDK import | Build failure or bloat | Platform-specific SDK package |
| Ignoring 429s | Data loss at peak traffic | Spike protection + circuit breaker |
| No alerts | Bugs accumulate unnoticed | Three-tier alert rules |
Examples
Example 1: Full-stack audit of existing Sentry setup
Request: "Audit our Sentry integration for common mistakes"
Result: Found hardcoded DSN in config.ts (Pitfall 1), 100% tracesSampleRate (Pitfall 2), no environment tag (Pitfall 7), and zero alert rules (Pitfall 10). Applied fixes for all four, added CI gate for DSN detection, created three-tier alert config. See examples for more scenarios.
Example 2: Debugging missing Lambda errors
Request: "Sentry shows no errors from our Lambda functions but we know they're failing"
Result: Identified Pitfall 3 — no flush() call before Lambda return. Wrapped all handlers with Sentry.wrapHandler() from @sentry/aws-serverless. Events now appear within 5 seconds of invocation.
Example 3: Source map stack traces showing minified code
Request: "Sentry stack traces are all minified even though we upload source maps"
Result: SDK used release: "2.1.0" while CLI used "v2.1.0" (Pitfall 5). Unified both to $GIT_SHA via shared SENTRY_RELEASE env var. Stack traces now show original TypeScript source.
Resources
- Sentry JavaScript Troubleshooting
- Sentry Best Practices
- Sentry Configuration Options
- Sentry Source Maps
- Sentry Quota Management
- Sentry Alerts
Next Steps
- Run the scan commands from Step 1 against your codebase
- Fix pitfalls in priority order: Pitfall 1 (security) > Pitfall 3 (data loss) > Pitfall 10 (alerting)
- Add DSN CI gate to prevent regression
- Set up three-tier alert structure before further Sentry work
Similar Claude Skills & Agent Workflows
feishu-wiki
Feishu knowledge base navigation.
write-docs
Write BrowserOS feature documentation.
skill-developer
Create and manage Claude Code skills following Anthropic best practices.
documentation-lookup
This skill should be used when the user asks about libraries, frameworks, API references, or needs code examples.
教程美化方案
使用 VitePress 和 Element Plus 组件美化教程,提升可读性和交互性
material-component-doc
用于 FlowGram 物料库组件文档撰写的专用技能,提供组件文档生成、Story 创建、翻译等功能的指导和自动化支持