| Mobile (React Native) |
@sentry/react-native |
1 mobile projec
Integrate Sentry into CI/CD pipelines for automated release creation, source map uploads, and deploy notifications.
ReadWriteEditBash(gh:*)Bash(sentry-cli:*)Bash(npm:*)Bash(npx:*)GrepGlob
Sentry CI Integration
Overview
Sentry releases connect errors to the code that caused them. Automating release creation in CI/CD ensures every deploy has commit association (suspect commits), source maps for readable stack traces, and deployment tracking across environments. This skill covers sentry-cli commands, the official GitHub Action, build tool plugins (@sentry/webpack-plugin, @sentry/vite-plugin, @sentry/esbuild-plugin), and multi-platform CI configurations.
Prerequisites
- Sentry account with a project at sentry.io
SENTRY_AUTH_TOKEN — generate at sentry.io/settings/auth-tokens/ with scopes project:releases and org:read
SENTRY_ORG and SENTRY_PROJECT environment variables matching your organization and project slugs
- Source maps generated during your build step (
devtool: 'source-map' in webpack, build.sourcemap: true in Vite)
- Git integration installed in Sentry (sentry.io/settings/integrations/ — GitHub, GitLab, or Bitbucket) for commit association
sentry-cli available via npm install -g @sentry/cli, npx @sentry/cli, or the getsentry/sentry-cli Docker image
Instructions
Step 1 — Configure Environment Variables and Auth Token
Set up the three required environment variables in your CI platform. Every sentry-cli command reads these automatically.
# GitHub Actions — add as repository secrets:
# Settings > Secrets and variables > Actions > New repository secret
SENTRY_AUTH_TOKEN=sntrys_eyJ... # Internal integration token from sentry.io/settings/auth-tokens/
SENTRY_ORG=my-org # Organization slug (visible in sentry.io URL)
SENTRY_PROJECT=my-project # Project slug (Settings > Projects > project name)
# Required token scopes:
# project:releases — create releases, upload source maps, record deploys
# org:read — read organization data for --auto commit association
# GitLab CI — add under Settings > CI/CD > Variables (masked + protected)
# CircleCI — add under Project Settings > Environment Variables
For build tool plugins (@sentry/webpack-plugin, @sentry/vite-plugin, @sentry/esbuild-plugin), the same three environment variables are read automatically. No additional configuration needed.
Verify your token works locally before committing CI configuration:
export SENTRY_AUTH_TOKEN=sntrys_eyJ...
export SENTRY_ORG=my-org
export SENTRY_PROJECT=my-project
npx @sentry/cli info
# Should print organization name, project, and CLI version
Step 2 — Create the CI Release Pipeline
Troubleshoot common Sentry integration issues and fixes.
ReadGrepBash(npm:*)Bash(node:*)Bash(curl:*)Bash(npx:*)Bash(sentry-cli:*)Bash(python3:*)
Sentry Common Errors
Overview
Diagnose and fix the most frequently encountered Sentry SDK integration issues across Node.js, browser, and Python environments. Covers DSN validation, missing events, source map failures, rate limiting, SDK initialization ordering, serverless flush patterns, CORS configuration, and environment tagging.
Prerequisites
- Sentry SDK installed (
@sentry/node v8+, @sentry/browser v8+, or sentry-sdk for Python)
- Access to Sentry dashboard with project admin or member role
- Application logs available for inspection
sentry-cli installed for source map and release operations
Instructions
Step 1 — Detect the installed SDK and current configuration
!npm list @sentry/node @sentry/browser @sentry/react @sentry/nextjs 2>/dev/null | head -10 || echo "No Node.js Sentry SDK found"
!python3 -c "import sentry_sdk; print(f'sentry-sdk {sentry_sdk.VERSION}')" 2>/dev/null || echo "No Python sentry-sdk found"
!command -v sentry-cli >/dev/null && sentry-cli --version || echo "sentry-cli not installed"
Grep the project for Sentry initialization to identify the current configuration:
grep -rn "Sentry.init\|sentry_sdk.init" --include="*.ts" --include="*.js" --include="*.mjs" --include="*.py" . 2>/dev/null | head -20
Step 2 — DSN not set or invalid DSN format
The DSN (Data Source Name) tells the SDK where to send events. Format: https://<public-key>@<org>.ingest.sentry.io/<project-id>
Symptoms: No events arrive. SDK silently does nothing. debug: true shows "No DSN provided."
// WRONG — DSN is undefined because env var is missing or misspelled
Sentry.init({
dsn: process.env.SENTRI_DSN, // Typo in env var name
});
// CORRECT — validate DSN is present before init
const dsn = process.env.SENTRY_DSN;
if (!dsn) {
console.error('SENTRY_DSN environment variable is not set');
process.exit(1);
}
Sentry.init({
dsn: dsn.trim(),
debug: true, // Enable during troubleshooting
});
Python equivalent:
import os, sentry_sdk
dsn = os.environ.get("SENTRY_DSN")
if not dsn:
raise RuntimeError("SENTRY_DSN not set")
sentry_sdk.init(dsn=dsn.strip(), debug=True)
Step 3 — Events not appearing in dashboard
Symptoms: Sentry.captureException() runs without errors, but nothing shows up in the Sentry web UI.
Root causes and fixes:
beforeSend accidentally return
Optimize Sentry costs, reduce event volume, and manage quota spend.
ReadWriteEditGrepGlobBash(curl:*)Bash(node:*)Bash(npx:*)
Sentry Cost Tuning
Overview
Reduce Sentry spend by 60-95% through SDK-level sampling, server-side inbound filters, beforeSend event dropping, and quota management — without losing visibility into production errors that matter.
Prerequisites
- Active Sentry account with
org:read and project:read scopes on an auth token
- Access to the project's
Sentry.init() configuration (typically sentry.client.config.ts or instrument.ts)
- Current plan tier identified: Developer (free, 5K errors/mo), Team ($26/mo, 50K errors + 100K transactions), or Business ($80/mo, 100K errors + 500K transactions)
SENTRY_AUTH_TOKEN and SENTRY_ORG environment variables set for API calls
@sentry/node >= 8.0 or @sentry/browser >= 8.0 installed
Instructions
Step 1 — Audit Current Usage via the Stats API
Query the Sentry Usage Stats API to understand where volume comes from before making changes. This endpoint returns event counts grouped by category over any time period.
# Pull 30-day usage breakdown by category
curl -s -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
"https://sentry.io/api/0/organizations/$SENTRY_ORG/stats/usage/?statsPeriod=30d&groupBy=category&field=sum(quantity)&interval=1d" \
| python3 -c "
import json, sys
data = json.load(sys.stdin)
print('=== 30-Day Usage by Category ===')
for group in data.get('groups', []):
cat = group['by']['category']
total = sum(interval[1] for interval in group.get('series', {}).get('sum(quantity)', []))
print(f' {cat}: {total:,} events')
"
# Identify top error-producing projects
curl -s -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
"https://sentry.io/api/0/organizations/$SENTRY_ORG/stats/usage/?statsPeriod=30d&groupBy=project&category=error&field=sum(quantity)" \
| python3 -c "
import json, sys
data = json.load(sys.stdin)
projects = []
for group in data.get('groups', []):
proj = group['by']['project']
total = sum(interval[1] for interval in group.get('series', {}).get('sum(quantity)', []))
projects.append((proj, total))
projects.sort(key=lambda x: -x[1])
print('=== Top Error-Producing Projects ===')
for name, count in projects[:10]:
print(f' {name}: {count:,}')
"
Record the baseline numbers. You need these to measure savings after optimization.
Step 2 — Configure Error Sampling with sampleRate
The sampleRate option in Sentry.init() controls the percentage of error events sent to Sentry. Setting it to 0.1
Configure GDPR-compliant data handling, PII scrubbing, and data retention policies in Sentry.
ReadWriteEditGrepBash(curl:*)Bash(node:*)
Sentry Data Handling
Configure PII scrubbing, GDPR compliance, data retention, and audit controls for Sentry. This skill covers client-side filtering with beforeSend, server-side scrubbing rules, data subject erasure via API, and SOC 2 compliance patterns.
Overview
Sentry captures error context that often contains personally identifiable information (PII) — emails in stack traces, credit card numbers in request bodies, IP addresses in headers. Production deployments must scrub this data at two layers: client-side via beforeSend hooks (before data leaves the application) and server-side via Sentry's built-in Data Scrubber (defense in depth). GDPR requires additional controls: consent-based initialization, data subject deletion endpoints, and a signed Data Processing Agreement. This skill implements all three layers with TypeScript and Python examples, plus verification tests to prove scrubbing works end-to-end.
Prerequisites
- Sentry SDK v8 installed and initialized (
@sentry/node or sentry-sdk)
- Sentry project with Admin or Owner role (required for Security & Privacy settings)
- Compliance requirements documented (GDPR, HIPAA, PCI-DSS, or SOC 2)
- Auth token with
project:write and org:admin scopes for API operations
- Data Processing Agreement signed at https://sentry.io/legal/dpa/ (GDPR requirement)
Instructions
Step 1 — Client-Side PII Scrubbing with beforeSend
The first defense layer prevents PII from leaving your application. Configure beforeSend, beforeSendTransaction, and beforeBreadcrumb hooks during SDK initialization:
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
// CRITICAL: disable automatic PII collection
// When false, Sentry will NOT capture IP addresses, cookies, or user-agent
sendDefaultPii: false,
beforeSend(event) {
return scrubEvent(event);
},
beforeSendTransaction(event) {
return scrubEvent(event);
},
beforeBreadcrumb(breadcrumb) {
if (breadcrumb.data) {
const sensitiveKeys = ['password', 'token', 'secret', 'api_key', 'authorization'];
for (const key of sensitiveKeys) {
if (breadcrumb.data[key]) {
breadcrumb.data[key] = '[REDACTED]';
}
}
}
return breadcrumb;
},
});
Implement the scrubEvent function to strip PII from headers, request bodies, error messages, and user context:
function scrubEvent(event: Sentry.Event): Sentry.Event | null {
// Strip sensitive headers
if (event.request?.headers) {
const redactHeaders = ['Authorization', 'Cookie', 'X-Api-Key&
Collect diagnostic information for Sentry troubleshooting and support tickets.
ReadWriteEditBash(npm:*)Bash(node:*)Bash(npx:*)Bash(pip:*)Bash(python:*)Bash(curl:*)Bash(dig:*)Bash(sentry-cli:*)GrepGlob
Sentry Debug Bundle
Overview
Collect SDK versions, configuration state, network connectivity, and event delivery status into a single diagnostic report. Attach the output to Sentry support tickets or use it to systematically isolate why events are not reaching the dashboard.
Current State
!node --version 2>/dev/null || echo 'Node.js not found' !python3 --version 2>/dev/null || echo 'Python3 not found' !npm list @sentry/node @sentry/browser @sentry/react @sentry/cli 2>/dev/null | grep sentry || pip show sentry-sdk 2>/dev/null | grep -E '^(Name|Version)' || echo 'No Sentry SDK found' !sentry-cli --version 2>/dev/null || echo 'sentry-cli not installed' !sentry-cli info 2>/dev/null || echo 'sentry-cli not authenticated'
Prerequisites
- At least one Sentry SDK installed (
@sentry/node, @sentry/browser, @sentry/react, or sentry-sdk for Python)
SENTRY_DSN environment variable set (or DSN configured in application code)
- For API checks:
SENTRY_AUTH_TOKEN with project:read scope (generate token)
- Optional:
sentry-cli installed for source map diagnostics and send-event tests
Instructions
Step 1 — Gather SDK Version, Configuration, and Init Hooks
Identify the installed SDK, verify all @sentry/* packages share the same version (mismatches cause silent failures), and extract the runtime configuration.
Check installed packages:
# Node.js — list all Sentry packages and flag version mismatches
npm ls @sentry/node @sentry/browser @sentry/react @sentry/nextjs @sentry/cli 2>/dev/null | grep sentry
# Python — show sentry-sdk version and installed extras
pip show sentry-sdk 2>/dev/null
Extract runtime configuration (Node.js):
import * as Sentry from '@sentry/node';
const client = Sentry.getClient();
if (!client) {
console.error('ERROR: Sentry client not initialized — Sentry.init() may not have been called');
process.exit(1);
}
const opts = client.getOptions();
const diagnostics = {
sdk_version: Sentry.SDK_VERSION,
dsn_configured: !!opts.dsn,
dsn_host: opts.dsn ? new URL(opts.dsn).hostname : 'N/A',
dsn_project_id: opts.dsn ? new URL(opts.dsn).pathname.replace('/', '') : 'N/A',
environment: opts.environment ?? '(default)',
release: opts.release ?? '(auto-detect)',
debug: opts.debug ?? false,
sample_rate: opts.sampleRate ?? 1.0,
traces_sample_rate: opts.tracesSampleRate ?? '(not set)',
profiles_sample_rate: opts.profile
Track deployments and release health in Sentry.
ReadWriteEditBash(sentry-cli:*)Bash(curl:*)Bash(node:*)Bash(npx:*)Grep
Sentry Deploy Integration
Overview
Wire Sentry into your deploy pipeline so every release is tracked end-to-end: commit association, source map upload, deploy recording, and post-deploy health monitoring. Sentry links errors to the exact deploy and suspect commit that introduced them, giving you crash-free session rates, adoption curves, and regression alerts per release.
Prerequisites
- Sentry CLI installed (
npm i -g @sentry/cli or curl -sL https://sentry.io/get-cli/ | bash)
SENTRY_AUTH_TOKEN with project:releases and org:read scopes
SENTRY_ORG and SENTRY_PROJECT environment variables set
@sentry/node v8+ installed in your application
- Source control integration enabled in Sentry (Settings > Integrations > GitHub/GitLab)
Instructions
Step 1 --- Record Deploys with sentry-cli
Create a release, associate commits for suspect-commit linking, and record the deployment with timing metadata.
#!/bin/bash
# scripts/sentry-deploy.sh
set -euo pipefail
VERSION="${1:-$(sentry-cli releases propose-version)}"
ENVIRONMENT="${2:-production}"
DEPLOY_START=$(date +%s)
# Create release and associate commits (enables suspect commits)
sentry-cli releases new "$VERSION"
sentry-cli releases set-commits "$VERSION" --auto
# Upload source maps for readable stack traces
sentry-cli sourcemaps upload \
--release="$VERSION" \
--url-prefix="~/static/js" \
--validate \
./dist
# Finalize marks the release as ready
sentry-cli releases finalize "$VERSION"
# --- Deploy your application here ---
# e.g., kubectl set image deployment/app app=myapp:$VERSION
DEPLOY_END=$(date +%s)
# Record the deployment in Sentry with timestamps
sentry-cli releases deploys "$VERSION" new \
-e "$ENVIRONMENT" \
-t "$DEPLOY_START" \
-f "$DEPLOY_END"
echo "Sentry deploy recorded: $VERSION -> $ENVIRONMENT ($(( DEPLOY_END - DEPLOY_START ))s)"
For multi-environment promotion (staging then production):
# Stage 1: deploy to staging
sentry-cli releases deploys "$VERSION" new -e staging
# Stage 2: after QA passes, deploy to production
sentry-cli releases deploys "$VERSION" new -e production
# Sentry dashboard shows the full promotion timeline
Step 2 --- Tag Releases in the SDK and Monitor Health
Configure the Sentry SDK with the release tag so crash-free session/user metrics, adoption rates, and error attribution bind to each release.
// src/instrument.ts
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE, //
Configure enterprise role-based access control, SSO/SAML2, and SCIM provisioning in Sentry.
ReadWriteEditGrepBash(curl:*)Bash(python3:*)Bash(jq:*)
Sentry Enterprise RBAC
Overview
Configure Sentry's Organization-Team-Project hierarchy, role assignments, SSO/SAML2 federation, SCIM automated provisioning, API token governance, and audit logging. Covers the full enterprise access control lifecycle from initial setup through ongoing compliance monitoring.
Prerequisites
- Sentry Business or Enterprise plan — team-level roles, SSO, SCIM, and audit logs require Business tier or higher
- Organization Owner or Manager role — only these roles can configure auth, teams, and member roles
- Identity Provider access — admin credentials for Okta, Azure AD, or Google Workspace if configuring SSO/SCIM
- Environment variables set:
export SENTRY_AUTH_TOKEN="sntrys_..." # Auth token with org:admin, member:admin, team:admin scopes
export SENTRY_ORG="your-org-slug" # Organization slug from sentry.io/settings/
Instructions
Step 1 — Establish the Organization-Team-Project Hierarchy
Sentry's access model flows top-down: Organization > Teams > Projects. Members inherit permissions from their org-level role, then gain project access through team membership.
Organization-level roles define the ceiling of what a member can do:
| Role |
Capabilities |
Typical Use |
| Owner |
Full control: billing, auth, members, all settings. Irremovable. |
Founding eng, CTO |
| Manager |
Manage all teams, projects, and members. No billing access. |
Engineering managers |
| Admin |
Manage integrations, projects, teams. No member management. |
Tech leads, DevOps |
| Member |
View data, act on issues, join/leave teams. Default for new users. |
Individual contributors |
| Billing |
Payment and subscription management only. No technical access. |
Finance team |
Team-level roles (Business/Enterprise only) add granularity within teams:
| Team Role |
Additional Capabilities |
| Team Admin |
Manage team membership, add/remove projects from the team |
| Contributor |
View and act on issues in the team's projects |
A member's effective permissions are the union of their org-level role and all team-level roles they hold. A Member with Team Admin on "payments-team" can manage that team but cannot touch org-wide settings.
Create the
Implement advanced error capture and context enrichment with Sentry.
ReadWriteEditGrepGlobBash(npm:*)Bash(npx:*)Bash(pip:*)Bash(python:*)
Sentry Error Capture
Overview
Capture errors and enrich them with structured context so your team can diagnose production issues in seconds instead of hours. Covers captureException, captureMessage, scoped context (withScope / push_scope), breadcrumbs, custom fingerprinting, and beforeSend filtering using @sentry/node v8 and sentry-sdk v2 APIs.
Prerequisites
- Sentry SDK installed and initialized (
@sentry/node v8+ or sentry-sdk v2+)
- A valid DSN configured via environment variable (
SENTRY_DSN)
- Understanding of try/catch (JS) or try/except (Python) error handling
- A Sentry project created at sentry.io
Instructions
Step 1 -- Capture Exceptions with Full Stack Traces
Always pass real Error objects (or Python exception instances), never plain strings. Plain strings lose the stack trace, making debugging far harder.
TypeScript (@sentry/node)
import * as Sentry from '@sentry/node';
// CORRECT -- full stack trace preserved
try {
await riskyOperation();
} catch (error) {
Sentry.captureException(error);
}
// WRONG -- no stack trace, hard to debug
Sentry.captureException('something went wrong');
// Wrapping non-Error values into proper Error objects
Sentry.captureException(new Error(`API returned ${statusCode}: ${body}`));
// Capture with inline context (no scope needed for simple cases)
Sentry.captureException(error, {
tags: { transaction: 'purchase' },
extra: { orderId, amount },
});
Python (sentry-sdk)
import sentry_sdk
# CORRECT -- full traceback preserved
try:
risky_operation()
except Exception as e:
sentry_sdk.capture_exception(e)
# Capture current exception implicitly (inside except block)
try:
risky_operation()
except Exception:
sentry_sdk.capture_exception() # captures sys.exc_info() automatically
Step 2 -- Capture Messages for Non-Exception Events
Use captureMessage for events that are not exceptions but still worth tracking: deprecation warnings, capacity thresholds, business logic anomalies.
TypeScript
// Severity levels: 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'log'
Sentry.captureMessage('Payment processed successfully', 'info');
Sentry.captureMessage('Deprecated API endpoint accessed', 'warning');
Sentry.captureMessage('Database connection pool exhausted', 'fatal');
Python
sentry_sdk.capture_m
Capture your first test error with Sentry and verify it appears in the dashboard.
ReadWriteEditBash(node:*)Bash(python:*)Bash(npm:*)Grep
Sentry Hello World
Overview
Send your first test events to Sentry — a captured message, a captured exception, and a fully-enriched error with user context, tags, and breadcrumbs — then verify each one appears in the Sentry dashboard. This skill covers both Node.js (@sentry/node) and Python (sentry-sdk).
Prerequisites
- Completed
sentry-install-auth setup (SDK installed, DSN configured)
- Valid
SENTRY_DSN in environment variables
instrument.mjs loaded before app code (Node.js) or sentry_sdk.init() called (Python)
- Network access to
*.ingest.sentry.io
Instructions
Step 1 — Verify the SDK Is Active
Before sending test events, confirm the SDK initialized correctly. If getClient() returns undefined, the SDK was never initialized — go back to sentry-install-auth.
TypeScript (Node.js):
import * as Sentry from '@sentry/node';
const client = Sentry.getClient();
if (!client) {
console.error('Sentry SDK not initialized. Ensure instrument.mjs is loaded first.');
console.error('Run with: node --import ./instrument.mjs your-script.mjs');
process.exit(1);
}
console.log('Sentry SDK active — DSN configured');
Python:
import sentry_sdk
client = sentry_sdk.Hub.current.client
if client is None or client.dsn is None:
print("Sentry SDK not initialized. Call sentry_sdk.init() first.")
exit(1)
print("Sentry SDK active — DSN configured")
Step 2 — Capture a Test Message
captureMessage sends an informational event without a stack trace. Use it to verify basic connectivity between your app and Sentry.
TypeScript:
import * as Sentry from '@sentry/node';
// captureMessage returns the event ID (a 32-char hex string)
const eventId = Sentry.captureMessage('Hello Sentry! SDK verification test.', 'info');
console.log(`Message sent — Event ID: ${eventId}`);
// Also test 'warning' level — appears with yellow indicator in dashboard
Sentry.captureMessage('Warning-level test message', 'warning');
// IMPORTANT: flush before process exits or events may be lost
await Sentry.flush(2000);
Python:
import sentry_sdk
event_id = sentry_sdk.capture_message("Hello Sentry! SDK verification test.", level="info")
print(f"Message sent — Event ID: {event_id}")
sentry_sdk.capture_message("Warning-level test message", level="warning")
# Flush to ensure delivery before process exits
sentry_sdk.flush()
Execute incident response procedures using Sentry error monitoring.
ReadWriteEditGrepBash(curl:*)Bash(node:*)Bash(npx:*)Bash(python3:*)
Sentry Incident Runbook
Overview
Structured incident response framework built on Sentry's error monitoring platform. Covers the full lifecycle from alert detection through severity classification, root cause investigation using Sentry's breadcrumbs and stack traces, Discover queries for impact analysis, stakeholder communication, resolution via the Sentry API, and postmortem documentation with Sentry data exports.
Prerequisites
- Sentry account with project-level access and auth token (
SENTRY_AUTH_TOKEN)
- Organization slug (
SENTRY_ORG) and project slug (SENTRY_PROJECT) configured
@sentry/node (v8+) or equivalent SDK installed in the application
- Alert rules configured for critical error thresholds
- Notification channels connected (Slack integration or PagerDuty)
Instructions
Step 1 — Classify Severity
Assign a severity level based on error frequency and user impact. This determines response time and escalation path.
| Severity |
Error Criteria |
User Impact |
Response Time |
Escalation |
| P0 — Critical |
Crash-free rate below 95% or unhandled exception spike >500/min |
Core flow blocked for all users, data loss risk |
15 minutes |
PagerDuty page to on-call engineer |
| P1 — Major |
New issue affecting >100 unique users per hour |
Key feature degraded, no workaround |
1 hour |
Slack #incidents channel, tag team lead |
| P2 — Minor |
New issue affecting <100 unique users per hour |
Feature degraded but workaround exists |
Same business day |
Slack #alerts-production |
| P3 — Low |
Edge case, cosmetic error, staging-only issue |
Minimal or no user-facing impact |
Next sprint |
Add to backlog, assign owner |
Decision logic for classification:
Alert fires →
├── Check crash-free rate (Project Settings → Crash Free Sessions)
│ └── Below 95%? → P0
├── Check unique users affected (Issue Details → Users tab)
│ ├── >100/hr on core flow? → P1
│ └── <100/hr or workaround exists? → P2
└── Staging-only or edge case? → P3
Step 2 — Triage and Investigate
Execute this checklist within the first 15 minutes of a P0/P1 alert.
Initial triage (Sentry UI):
- Open the Sentry issue link from the alert notification
- Check the error frequency graph — determine if the rate is spiking, steady, or declining
- Read the "First Seen" and "Last Seen" timestamps to determine if this is new or a regression
- Check the &qu
Install and configure Sentry SDK authentication with DSN setup.
ReadWriteEditBash(npm:*)Bash(pip:*)Grep
Sentry Install & Auth
Overview
Install the Sentry SDK, configure DSN-based authentication, and verify error tracking is operational. Covers Node.js (@sentry/node), browser (@sentry/browser), and Python (sentry-sdk) with environment-based configuration and auth token setup for CLI/CI workflows.
Prerequisites
- Node.js 18.19+ or 20.6+ (required for ESM support in Sentry SDK v8)
- Package manager: npm, pnpm, or pip
- Sentry account with a project created at https://sentry.io
- DSN from Project Settings > Client Keys (DSN)
- For CLI/CI: auth token from https://sentry.io/settings/auth-tokens/
Instructions
Step 1 — Install the SDK
Node.js / TypeScript:
npm install @sentry/node
# For profiling support (optional):
npm install @sentry/profiling-node
Browser / Framework-specific:
npm install @sentry/browser
# Or pick your framework:
npm install @sentry/react # React
npm install @sentry/nextjs # Next.js
npm install @sentry/vue # Vue
Python:
pip install sentry-sdk
Step 2 — Store the DSN securely
The DSN (Data Source Name) tells the SDK where to send events. It looks like https://<key>@<org>.ingest.sentry.io/<project-id>. Never hardcode it — use environment variables.
# .env (add this file to .gitignore)
SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0
SENTRY_ENVIRONMENT=development
SENTRY_RELEASE=1.0.0
For production, store the DSN in your secret manager (AWS Secrets Manager, GCP Secret Manager, Vault, etc.) and inject it at deploy time.
Step 3 — Initialize the SDK
Node.js (ESM) — create instrument.mjs at project root:
This file MUST be imported before any other modules. The --import flag ensures Sentry instruments HTTP, database, and framework integrations via monkey-patching at load time.
// instrument.mjs — import BEFORE your app code
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.SENTRY_ENVIRONMENT || 'development',
release: process.env.SENTRY_RELEASE,
// Performance: 100% in dev, 10-20% in production
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
// Debug mode — disable in production
debug: process.env.NODE_ENV !== 'production',
// Never send PII by default
sendDefaultPii: false,
integrations: [
// Built-in integrations (httpIntegration, expressIntegration)
// are auto-detected — no manual registration needed
],
});
Identify and fix common Sentry SDK pitfalls that cause silent data loss, cost overruns, and missed alerts.
ReadWriteEditGrepGlobBash(node:*)Bash(npm:*)Bash(npx:*)Bash(grep:*)Bash(find:*)
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/C
Scale Sentry for high-traffic applications handling millions of events per day.
ReadWriteEditGrepBash(node:*)Bash(npx:*)Bash(k6:*)
Sentry Load & Scale
Overview
Configure Sentry for applications processing 1M+ requests/day without sacrificing error visibility, burning through quota, or adding measurable SDK overhead. Covers adaptive sampling, connection pooling, multi-region tagging, quota management, SDK benchmarking, batch submission, load testing, and self-hosted deployment considerations.
Prerequisites
- Application handling sustained high traffic (>10K requests/min or >1M events/day)
- Sentry organization with quota and billing access (Settings > Subscription)
@sentry/node v8+ installed (npm ls @sentry/node)
- Performance baseline established (p50/p95/p99 latency without Sentry)
- Event volume estimates calculated per category (errors, transactions, replays, attachments)
Instructions
Step 1 — Implement Adaptive Sampling
Static tracesSampleRate wastes quota at scale because it treats a health check the same as a checkout. Replace it with a traffic-aware tracesSampler that adjusts rates based on endpoint criticality and current load.
Traffic-aware tracesSampler:
import * as Sentry from '@sentry/node';
// Track request volume per endpoint for adaptive rate adjustment
const endpointVolume = new Map<string, { count: number; resetAt: number }>();
const WINDOW_MS = 60_000;
function getAdaptiveRate(name: string, baseRate: number): number {
const now = Date.now();
let entry = endpointVolume.get(name);
if (!entry || now > entry.resetAt) {
entry = { count: 0, resetAt: now + WINDOW_MS };
endpointVolume.set(name, entry);
}
entry.count++;
// Scale down sampling as volume increases within window
// 0-100 req/min: full base rate
// 100-1000: halve it
// 1000+: quarter it
if (entry.count > 1000) return baseRate * 0.25;
if (entry.count > 100) return baseRate * 0.5;
return baseRate;
}
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampler: (samplingContext) => {
const { name, parentSampled } = samplingContext;
// Always respect parent decision for distributed tracing consistency
if (parentSampled !== undefined) return parentSampled ? 1.0 : 0;
// Tier 0: Never sample — high-frequency, zero diagnostic value
if (name?.match(/\/(health|ready|alive|ping|metrics|favicon)/)) return 0;
if (name?.match(/\.(css|js|png|jpg|svg|woff2?|ico)$/)) return 0;
// Tier 1: Always sample — business-critical, low volume
if (name?.includes('/payment') || name?.includes('/checkout')) return 1.0;
if (name?.includes('/auth/login')) return getAdaptiveRate('auth', 0.5);
// Tier 2: Moderate sampling — API mutations (higher signal)
if (name?.startsWith('POST /api/')) return getAdaptiveRate(name, 0.05);
if (name?.startsWith('PUT /a
Configure Sentry for local development with environment-aware settings.
ReadWriteEditBash(npm:*)Bash(node:*)Bash(npx:*)Bash(python:*)GrepGlob
Sentry Local Dev Loop
Overview
Configure Sentry for local development with environment-aware DSN routing, debug-mode verbosity, full-capture sample rates, beforeSend inspection, Sentry Spotlight for offline event viewing, and sentry-cli source map verification. All configuration uses environment variables so nothing leaks into commits.
Prerequisites
@sentry/node v8+ installed (TypeScript/Node) or sentry-sdk v2+ installed (Python)
- Separate Sentry project created for development (different DSN from production)
.env file with SENTRY_DSN_DEV and NODE_ENV=development
- Network access to
*.ingest.sentry.io (or use Spotlight for fully offline work)
Instructions
Step 1 -- Environment-Aware Configuration
Create an initialization file that routes events to the correct Sentry project based on environment, enables debug logging in dev, and captures 100% of traces locally:
// instrument.mjs — import via: node --import ./instrument.mjs app.mjs
import * as Sentry from '@sentry/node';
const env = process.env.NODE_ENV || 'development';
const isDev = env !== 'production';
Sentry.init({
// Route to dev project locally, prod project in production
dsn: isDev
? process.env.SENTRY_DSN_DEV
: process.env.SENTRY_DSN,
environment: env,
release: isDev ? 'dev-local' : process.env.SENTRY_RELEASE,
// Full capture in dev — you need every event for debugging
tracesSampleRate: isDev ? 1.0 : 0.1,
sampleRate: isDev ? 1.0 : 1.0,
// Verbose SDK output to console in dev
debug: isDev,
// Include PII locally for easier debugging (never in prod)
sendDefaultPii: isDev,
// Sentry Spotlight — shows events in local browser UI
// Install: npx @spotlightjs/spotlight
spotlight: isDev,
beforeSend(event, hint) {
if (isDev) {
const exc = event.exception?.values?.[0];
const label = exc
? `${exc.type}: ${exc.value}`
: event.message || 'event';
console.log(`[Sentry Dev] ${label}`);
console.log(` Tags: ${JSON.stringify(event.tags || {})}`);
}
return event;
},
beforeSendTransaction(event) {
if (isDev) {
const duration = event.timestamp && event.start_timestamp
? ((event.timestamp - event.start_timestamp) * 1000).toFixed(0)
: '?';
console.log(`[Sentry Dev] Transaction: ${event.transaction} (${duration}ms)`);
}
return event;
},
});
Set up environment files to keep DSNs out of source:
# .env.development
SENTRY_DSN_DEV=https://examplePublicKey@o0.ingest.sentry.io/0
SENTRY_ENVIRONMENT=development
NODE_ENV=development
# .env.production
SENTRY_DSN=https://prodPublicKey@o0.ingest.sentry.io/0
SENTRY_ENVIRONMENT=production
SE
Migrate to Sentry from other error tracking tools like Rollbar, Bugsnag, or New Relic.
ReadWriteEditBash(npm:*)Bash(npx:*)Bash(node:*)GrepGlob
Sentry Migration Deep Dive
Overview
Replace an existing error tracking tool (Rollbar, Bugsnag, New Relic, Raygun, Airbrake) with Sentry using a phased migration that runs both tools in parallel before cutover. This skill covers concept mapping between providers, SDK swap patterns, alert rule migration, team training, and rollback strategy.
Current State
!npm list 2>/dev/null | command grep -iE "sentry|rollbar|bugsnag|raygun|airbrake|honeybadger|newrelic" || echo 'No error tracking packages found'
Prerequisites
- Admin access to the current error tracking tool (API keys, alert rule access)
- Sentry project created with DSN available in environment variables
- Source maps or debug symbols configured for stack trace resolution
- Parallel run timeline agreed with team (2-4 weeks recommended)
- Inventory of current alert rules, integrations, and custom filters
Instructions
Step 1: Map Concepts Between Providers
Build a translation table mapping the current tool's terminology and API surface to Sentry equivalents. Scan the codebase for all calls to the existing SDK.
| Concept |
Rollbar |
Bugsnag |
New Relic |
Sentry |
| Capture error |
rollbar.error(err) |
Bugsnag.notify(err) |
newrelic.noticeError(err) |
Sentry.captureException(err) |
| Log message |
rollbar.info(msg) |
Bugsnag.notify(msg) |
newrelic.recordCustomEvent() |
Sentry.captureMessage(msg) |
| User context |
rollbar.configure({ person: {...} }) |
Bugsnag.setUser(id, email) |
newrelic.setUserID(id) |
Sentry.setUser({ id, email }) |
| Tags/metadata |
rollbar.configure({ custom: {...} }) |
bugsnag.addMetadata(tab, data) |
newrelic.addCustomAttributes() |
Sentry.setTag() / Sentry.setContext() |
| Breadcrumbs |
rollbar.log(level, msg) |
Bugsnag.leaveBreadcrumb(msg) |
N/A |
Sentry.addBreadcrumb({ message }) |
| Release tracking |
code_version config |
appVersion config |
NEW_RELIC_LABELS |
Sentry.init({ release: 'v1.2.3' }) |
| Environment |
environment config |
releaseStage config |
NEW_RELIC_APP_NAME suffix |
Sentry.init({ environment: 'prod' }) |
| Error filter |
checkIgnor
Configure Sentry across development, staging, and production environments with separate DSNs, environment-specific sample rates, per-environment alert rules, and dashboard filtering.
ReadWriteEditGrepGlobBash(npm:*)Bash(npx:*)Bash(node:*)Bash(sentry-cli:*)
Sentry Multi-Environment Setup
Overview
Configure Sentry to run across development, staging, and production with isolated DSNs, tuned sample rates, environment-aware alert routing, and dashboard filtering. Covers @sentry/node v8+ (TypeScript) and sentry-sdk v2+ (Python), targeting sentry.io or self-hosted Sentry 24.1+. The goal is to capture everything in dev, validate in staging, and protect production with tight sampling and PII scrubbing.
Prerequisites
- Sentry organization at sentry.io with at least one project created
@sentry/node v8+ installed (npm install @sentry/node) or sentry-sdk v2+ (pip install sentry-sdk)
- Environment naming convention agreed upon (this guide uses
development, staging, production)
- DSN strategy decided: single project with environment tags or separate projects per environment (see project-structure-options.md)
.env file management tooling (dotenv, direnv, or platform-native env config)
Instructions
Step 1 — Create Environment-Aware SDK Configuration with Separate DSNs
Each environment gets its own DSN pointing to a dedicated Sentry project. This prevents dev noise from inflating production quotas and allows independent rate limits per environment.
Set up .env files per environment:
# .env.development
SENTRY_DSN=https://dev-key@o0.ingest.sentry.io/111
SENTRY_ENVIRONMENT=development
SENTRY_RELEASE=local-dev
# .env.staging
SENTRY_DSN=https://staging-key@o0.ingest.sentry.io/222
SENTRY_ENVIRONMENT=staging
# .env.production
SENTRY_DSN=https://prod-key@o0.ingest.sentry.io/333
SENTRY_ENVIRONMENT=production
TypeScript — environment-aware init with typed config:
// config/sentry.ts
import * as Sentry from '@sentry/node';
type Environment = 'development' | 'staging' | 'production';
interface EnvSentryConfig {
tracesSampleRate: number;
sampleRate: number;
debug: boolean;
sendDefaultPii: boolean;
maxBreadcrumbs: number;
enabled: boolean;
}
const ENV_CONFIG: Record<Environment, EnvSentryConfig> = {
development: {
tracesSampleRate: 1.0, // Capture every transaction for local debugging
sampleRate: 1.0, // Every error
debug: true, // Verbose console output for SDK troubleshooting
sendDefaultPii: true, // Include PII for local debugging only
maxBreadcrumbs: 100, // Full breadcrumb trail
enabled: true, // Set to false to fully disable in dev
},
staging: {
tracesSampleRate: 0.5, // 50% of transactions — enough to catch regressions
samp
Integrate Sentry with your observability stack — logging, metrics, APM, and dashboards.
ReadWriteEditGrepBash(node:*)Bash(npx:*)Bash(pip:*)
Sentry Observability Integration
Overview
Wire Sentry into your logging, metrics, APM, and dashboard toolchain so every error carries full context and every metric correlates back to root-cause events. This skill covers three integration layers: structured logging (winston, pino, structlog) with Sentry event ID correlation, business metrics with error-rate tracking, and cross-tool linking via Sentry Discover, Grafana webhooks, and APM tools.
See also: Logging integration details | Metrics patterns | APM tool cross-linking
Prerequisites
- Sentry SDK v8+ installed (
@sentry/node for Node.js, sentry-sdk for Python)
- At least one structured logger configured (winston, pino, or structlog)
- Sentry project DSN available in environment (
SENTRY_DSN)
- Dashboard platform accessible (Sentry Discover, Grafana, or Datadog)
- Alert routing strategy decided (who gets paged, where warnings go)
Instructions
Step 1 — Attach Sentry Event IDs to Structured Logs
The core pattern: every log line that triggers a Sentry event carries the event ID, and every Sentry event carries the log context. This creates a two-way link between your log aggregator and Sentry.
Winston (Node.js) — custom transport:
import winston from 'winston';
import * as Sentry from '@sentry/node';
class SentryTransport extends winston.Transport {
log(info: any, callback: () => void) {
setImmediate(callback);
if (info.level === 'error' || info.level === 'fatal') {
const error = info.error instanceof Error
? info.error
: new Error(info.message);
Sentry.withScope((scope) => {
scope.setTag('logger', 'winston');
scope.setContext('log_entry', {
level: info.level,
timestamp: info.timestamp,
service: info.service,
});
const eventId = Sentry.captureException(error);
info.sentry_event_id = eventId;
info.sentry_url = `https://${process.env.SENTRY_ORG}.sentry.io/issues/?query=${eventId}`;
});
}
}
}
const logger = winston.createLogger({
defaultMeta: { service: 'api-gateway' },
transports: [
new winston.transports.Console({ format: winston.format.json() }),
new SentryTransport(),
],
});
Pino (Node.js) — hooks pattern:
import pino from 'pino';
import * as Sentry from '@sentry/node';
const logger = pino({
hooks: {
logMethod(inputArgs, method, level) {
if (level >= 50) { // 50 = error, 60 = fatal
const [obj, msg] = typeof inputArgs[0] === '
Set up performance monitoring and distributed tracing with Sentry.
ReadWriteEditGrepBash(node:*)
Sentry Performance Tracing
Overview
Sentry performance monitoring captures distributed traces across your application stack, measuring latency, identifying bottlenecks, and tracking Web Vitals. The v8 SDK uses a span-based API where Sentry.startSpan() replaces the deprecated startTransaction(). Auto-instrumentation covers HTTP, database queries, and framework routes out of the box. Manual spans let you measure business-critical operations. Combined with profiling (profilesSampleRate), you get function-level flamegraphs attached to traces.
Prerequisites
- Sentry SDK v8+ installed (
@sentry/node >= 8.0.0 or sentry-sdk >= 2.0.0)
tracesSampleRate > 0 set in Sentry.init() — performance data is not collected at zero
- Performance monitoring enabled in your Sentry project settings (Settings > Performance)
- For distributed tracing: all participating services must have Sentry SDK initialized
Instructions
Step 1 — Configure Tracing and Profiling in SDK Init
Set tracesSampleRate to control what percentage of requests generate traces. Use tracesSampler for dynamic, per-endpoint sampling. Add profilesSampleRate to attach function-level flamegraphs to sampled transactions.
TypeScript (@sentry/node):
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 0.2, // 20% of transactions in production
// Profiling — profiles 10% of sampled transactions
profilesSampleRate: 0.1,
// Dynamic sampling overrides tracesSampleRate when defined
tracesSampler: (samplingContext) => {
const { name, attributes } = samplingContext;
// Drop health checks entirely — no trace data
if (name === 'GET /health') return 0;
// Always trace payment flows
if (name?.includes('/api/payment')) return 1.0;
// Higher sampling for API routes
if (name?.startsWith('GET /api/') || name?.startsWith('POST /api/')) return 0.2;
// Default: 5% for everything else
return 0.05;
},
});
Python (sentry-sdk):
import os
import sentry_sdk
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
traces_sample_rate=0.2, # 20% of transactions
profiles_sample_rate=0.1, # 10% of sampled transactions get profiled
# Dynamic sampling via traces_sampler (overrides traces_sample_rate)
traces_sampler=lambda ctx: (
0.0 if ctx.get("transaction_context", {}).get("name") == "GET /health"
else 1.0 if "/api/payment" in ctx.get("transaction_context", {}).get("name", "")
else
Optimize Sentry performance monitoring for lower overhead and higher signal.
ReadWriteEditGrepGlobBash(npm:*)Bash(npx:*)Bash(node:*)Bash(sentry-cli:*)
Sentry Performance Tuning
Overview
Optimize Sentry's performance monitoring pipeline to maximize signal quality while minimizing SDK overhead and event volume costs. Covers the v8 SDK API for @sentry/node, @sentry/browser, and sentry-sdk (Python), targeting sentry.io or self-hosted Sentry 24.1+.
Prerequisites
- Sentry SDK v8+ installed (
@sentry/node >= 8.0.0 or sentry-sdk >= 2.0.0)
Sentry.init() called with a valid DSN before any application code runs
- Performance monitoring enabled (
tracesSampleRate > 0 or a tracesSampler function)
- Access to the Sentry Performance dashboard to verify changes
Instructions
Step 1 — Replace Static tracesSampleRate with Dynamic tracesSampler
A flat tracesSampleRate: 0.1 samples all routes equally. The tracesSampler callback makes per-transaction decisions based on route, operation type, and upstream trace context.
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
// tracesSampler replaces tracesSampleRate — do not set both
tracesSampler: (samplingContext) => {
const { name, attributes, parentSampled } = samplingContext;
// Honor parent sampling for distributed trace consistency
if (parentSampled !== undefined) return parentSampled ? 1.0 : 0;
// Drop noise — health probes, static assets
if (name?.match(/\/(health|ready|alive|ping|metrics)$/)) return 0;
if (name?.match(/\.(js|css|png|jpg|svg|woff2?|ico)$/)) return 0;
// Always sample business-critical paths
if (name?.includes('/checkout') || name?.includes('/payment')) return 1.0;
// Higher sampling for write operations (mutations are riskier)
if (name?.startsWith('POST ') || name?.startsWith('PUT ')) return 0.25;
// Moderate sampling for read APIs
if (name?.startsWith('GET /api/')) return 0.1;
// Low sampling for background work
if (name?.startsWith('job:') || name?.startsWith('queue:')) return 0.05;
// User-tier sampling (via custom attributes from middleware)
if (attributes?.['user.plan'] === 'enterprise') return 0.5;
return 0.05; // Default: 5%
},
});
Step 2 — Configure Profiling with profilesSampleRate
The profilesSampleRate controls what fraction of traced transactions get profiled. Setting it to 1.0 with a 5% tracesSampler means 5% of traffic is profiled.
import { nodeProfilingIntegration } from '@sentry/profiling-node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [nodeProfilingIntegration()],
tracesSampler: (ct
Enforce organizational governance and policy guardrails for Sentry usage.
ReadWriteEditGrepGlobBash(node:*)Bash(npm:*)Bash(npx:*)Bash(curl:*)Bash(grep:*)Bash(git:*)
Sentry Policy Guardrails
Overview
Organizational governance framework that prevents Sentry configuration drift across multiple services. A shared npm package (@company/sentry-config) wraps Sentry.init() to enforce PII scrubbing, naming conventions, tagging standards, and per-tier trace rate caps. CI checks block policy violations before merge, and a monthly drift audit detects projects that have fallen out of compliance.
Prerequisites
@sentry/node v8+ installed in target services
- Internal npm registry available (GitHub Packages, Artifactory, or similar)
- Team structure and project ownership defined in Sentry
SENTRY_AUTH_TOKEN with org:read and project:read scopes
- Compliance requirements identified (SOC 2, GDPR, HIPAA)
Instructions
Step 1 — Build the Shared Configuration Package
Create @company/sentry-config that wraps Sentry.init() with non-negotiable defaults.
Mandatory PII scrubbing (cannot be bypassed):
// @company/sentry-config/src/scrubbers.ts
import type { Event } from '@sentry/node';
const SENSITIVE_HEADERS = [
'authorization', 'cookie', 'set-cookie',
'x-api-key', 'x-auth-token', 'x-csrf-token',
];
const PII_PATTERNS = [
{ pattern: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{1,7}\b/g, replacement: '[CC_REDACTED]' },
{ pattern: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, replacement: '[EMAIL_REDACTED]' },
{ pattern: /\b\d{3}-\d{2}-\d{4}\b/g, replacement: '[SSN_REDACTED]' },
];
export function scrubEvent(event: Event): Event | null {
if (event.request?.headers) {
for (const h of SENSITIVE_HEADERS) delete event.request.headers[h];
}
if (event.message) event.message = scrubPII(event.message);
if (event.exception?.values) {
for (const exc of event.exception.values) {
if (exc.value) exc.value = scrubPII(exc.value);
}
}
return event;
}
function scrubPII(str: string): string {
for (const { pattern, replacement } of PII_PATTERNS) {
str = str.replace(new RegExp(pattern.source, pattern.flags), replacement);
}
return str;
}
Governed init with naming validation, tag injection, and tier-based caps:
// @company/sentry-config/src/index.ts
import * as Sentry from '@sentry/node';
import { scrubEvent } from './scrubbers';
const ENFORCED: Partial<Sentry.NodeOptions> = {
sendDefaultPii: false,
debug: false,
maxBreadcrumbs: 50,
sampleRate: 1.0,
maxValueLength: 500,
};
const VALID_ENVS = ['production', 'staging', 'development', 'canary', 'sandbox'];
const TIER_TRACE_CAPS: Record<string, number> = { critical
Production deployment checklist for Sentry integration.
ReadGrepGlobBash(npm:*)Bash(npx:*)Bash(node:*)Bash(curl:*)Bash(sentry-cli:*)
Sentry Production Deployment Checklist
Overview
Walk through every production-critical Sentry configuration item before a deploy — SDK init options, source map uploads, alert routing, PII scrubbing, sample rate tuning, and test error verification. Covers @sentry/node (v8+) and sentry-cli workflows.
Use when:
- Preparing a first production deploy with Sentry
- Auditing an existing Sentry config after an incident
- Running a go-live readiness review
- Onboarding a new service into Sentry monitoring
Prerequisites
@sentry/node (or framework-specific SDK like @sentry/nextjs, @sentry/react) installed
- Sentry project created with a dedicated production DSN (separate from dev/staging)
sentry-cli installed globally or as a devDependency (npm i -D @sentry/cli)
SENTRY_AUTH_TOKEN with scope project:releases available in CI environment
- Build pipeline that produces source maps
Instructions
Work through each section in order. Check off each item as you verify it.
Step 1 — DSN and Environment Variables
- [ ] DSN set via environment variable, not hardcoded in source code
// CORRECT — DSN from environment
Sentry.init({
dsn: process.env.SENTRY_DSN,
});
// WRONG — hardcoded DSN leaks project ID and org info
Sentry.init({
dsn: 'https://abc123@o456.ingest.sentry.io/789',
});
Verify with: grep -r "ingest.sentry.io" src/ --include="*.ts" --include="*.js" — should return zero results.
- [ ]
SENTRY_DSN set in production environment (not just .env.local)
- [ ]
SENTRY_ORG and SENTRY_PROJECT set for CLI operations
Step 2 — Environment Tag
- [ ]
environment tag set to 'production'
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV || 'production',
});
This enables environment-scoped alert rules and release health filtering. Without it, all events land in the default (empty) environment.
Step 3 — Release Tracking
- [ ]
release set to match the deploy version
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: 'production',
release: process.env.SENTRY_RELEASE || `myapp@${process.env.npm_package_version}`,
});
The release value must match exactly what you pass to sentry-cli releases new. Mismatches break source map
Manage Sentry rate limits, quotas, and event volume optimization.
ReadWriteEditGrepGlobBash(curl:*)Bash(node:*)Bash(python3:*)Bash(pip:*)
Sentry Rate Limits & Quota Optimization
Overview
Manage Sentry rate limits, sampling strategies, and quota usage to control costs without losing visibility into critical errors. Covers client-side sampling, beforeSend filtering, server-side inbound filters, per-key rate limits, spike protection, and the usage stats API.
Prerequisites
- Sentry account with a project DSN configured
SENTRY_AUTH_TOKEN with org:read and project:write scopes (Settings > Auth Tokens)
SENTRY_ORG and SENTRY_PROJECT slugs known
- SDK installed:
@sentry/node (npm) or sentry-sdk (pip)
- Current event volume visible at
sentry.io/stats/
Instructions
Step 1 — Understand Rate Limit Behavior
When your project exceeds its quota, Sentry returns 429 Too Many Requests with a Retry-After header. The SDK automatically stops sending events until the cooldown expires. Events generated during this window are permanently lost — there is no replay mechanism.
Rate limit tiers by plan:
| Plan |
API Rate Limit |
Notes |
| Developer |
50 RPM |
Shared quota, no reserved volume |
| Team |
1,000 RPM |
Per-organization, includes spike protection |
| Business |
10,000 RPM |
Per-organization, custom quotas available |
| Enterprise |
Custom |
Negotiated per contract |
Quota categories (billed separately):
- Errors — exceptions and log messages
- Transactions — performance monitoring spans
- Replays — session replay recordings
- Attachments — file uploads (crash dumps, minidumps)
- Profiles — continuous profiling data
- Cron monitors — scheduled job check-ins
Rate limit headers returned on 429:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-Sentry-Rate-Limit-Limit: 50
X-Sentry-Rate-Limit-Remaining: 0
X-Sentry-Rate-Limit-Reset: 1711324800
Step 2 — Configure Client-Side Sampling
Sampling is the first line of defense. Set sampleRate for errors and tracesSampleRate for performance transactions.
TypeScript / Node.js:
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
// Error sampling: 0.0 (drop all) to 1.0 (capture all)
sampleRate: 0.25, // Capture 25% of errors
// Transaction sampling: 0.0 to 1.0
tracesSampleRate: 0.1, // Capture 10% of transactions
// Dynamic transaction
Design production-grade Sentry architecture for multi-service organizations.
ReadWriteEditBash(npm:*)Bash(npx:*)GlobGrep
Sentry Reference Architecture
Overview
Enterprise Sentry architecture patterns for multi-service organizations. Covers centralized configuration, project topology, team-based alert routing, distributed tracing, error middleware, source map management, and a production-ready SentryService wrapper.
Prerequisites
- Sentry organization at sentry.io (Business plan+ for team features)
@sentry/node v8+ installed (npm install @sentry/node @sentry/profiling-node)
- Service inventory and team ownership documented
- Node.js 18+ (ESM and native fetch instrumentation)
Instructions
Step 1 — Project Structure Strategy
Pattern A: One Project Per Service (3+ services, recommended)
Organization: acme-corp
├── Team: platform-eng
│ ├── Project: api-gateway (Node/Express)
│ ├── Project: auth-service (Node/Fastify)
│ └── Project: user-service (Node/Express)
├── Team: payments
│ ├── Project: payment-api (Node/Express)
│ └── Project: billing-worker (Node worker)
└── Team: frontend
├── Project: web-app (React/Next.js)
└── Project: mobile-app (React Native)
Benefits: independent quotas, team-scoped alerts, per-service rate limits, isolated release tracking.
Pattern B: Shared Project (< 3 services, single team) — one project with Environment tags (production/staging/dev). Simpler setup; outgrow when alert noise exceeds one team.
Step 2 — Centralized Config Module
Create lib/sentry.ts imported by every service to enforce org-wide defaults:
// lib/sentry.ts
import * as Sentry from '@sentry/node';
import { nodeProfilingIntegration } from '@sentry/profiling-node';
export interface SentryServiceConfig {
serviceName: string;
dsn: string;
environment?: string;
version?: string;
tracesSampleRate?: number;
ignoredTransactions?: string[];
}
export function initSentry(config: SentryServiceConfig): void {
const env = config.environment || process.env.NODE_ENV || 'development';
Sentry.init({
dsn: config.dsn,
environment: env,
release: `${config.serviceName}@${config.version || 'unknown'}`,
serverName: config.serviceName,
tracesSampleRate: config.tracesSampleRate ?? (env === 'production' ? 0.1 : 1.0),
sendDefaultPii: false,
maxBreadcrumbs: 50,
integrations: [nodeProfilingIntegration()],
ignoreErrors: [
'ResizeObserver loop completed with undelivered notifications',
/Loading chunk \d+ failed/,
'AbortError',
],
tracesSampler: ({ name, parentSampled }) => {
if (parentSampled !== undefined) return parentSampled;
const ignored = config.ignoredTransactions || [
'GET /
Manage Sentry releases with versioning, commit association, and source map uploads.
ReadWriteEditBash(sentry-cli:*)Bash(npx:*)Bash(node:*)Bash(git:*)Grep
Sentry Release Management
Overview
Manage the full Sentry release lifecycle: create versioned releases, associate commits for suspect commit detection, upload source maps for readable stack traces, and monitor release health with crash-free rates and adoption metrics. Every production deploy should create a Sentry release so errors are grouped by version and regressions are caught immediately.
Prerequisites
- Sentry CLI installed:
npm install -g @sentry/cli (v2.x) or use npx @sentry/cli
- Auth token with
project:releases and org:read scopes from sentry.io/settings/auth-tokens/
- Environment variables set:
SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT
- Source maps generated by your build (e.g.,
tsc --sourceMap, Vite build.sourcemap: true)
- GitHub/GitLab integration installed in Sentry for automatic commit association (Settings > Integrations)
Instructions
Step 1 — Create a Release and Associate Commits
Choose a release naming convention. Sentry accepts any string, but two patterns dominate production usage:
Semver naming ties releases to your package version:
# Semver: my-app@2.1.0
VERSION="my-app@$(node -p "require('./package.json').version")"
sentry-cli releases new "$VERSION"
Commit SHA naming ties releases to exact deployments:
# SHA: my-app@a1b2c3d (short) or full 40-char SHA
VERSION="my-app@$(git rev-parse --short HEAD)"
sentry-cli releases new "$VERSION"
After creating the release, associate commits. This is what powers suspect commits — Sentry's ability to identify which commit likely caused a new issue by matching error stack frames to recently changed files:
# Auto-detect commits since last release (requires GitHub/GitLab integration)
sentry-cli releases set-commits "$VERSION" --auto
# Or specify a commit range manually
sentry-cli releases set-commits "$VERSION" \
--commit "my-org/my-repo@from_sha..to_sha"
When --auto runs, Sentry walks the git log from the previous release's last commit to the current HEAD. It stores each commit's author, changed files, and message. When a new error arrives, Sentry matches the stack trace file paths against recently changed files and suggests the author as the likely owner.
Step 2 — Upload Source Maps and Release Artifacts
Source maps let Sentry translate minified stack traces into original source code. Upload them
Build reliable Sentry integrations with graceful degradation, circuit breakers, and offline queuing.
ReadWriteEditGrepBash(node:*)Bash(pip:*)Bash(python*:*)
Sentry Reliability Patterns
Overview
Build Sentry integrations that never take your application down via three pillars: safe initialization with graceful degradation, a circuit breaker that stops hammering Sentry when unreachable, and an offline event queue that buffers errors during outages. Every pattern prioritizes application uptime over telemetry completeness.
Prerequisites
@sentry/node v8+ (TypeScript) or sentry-sdk v2+ (Python)
- A valid Sentry DSN from project settings at
sentry.io
- A fallback logging destination decided (console, file, or external logger)
- Understanding of your application shutdown lifecycle (signal handlers, container orchestration)
Instructions
Step 1 — Safe Initialization with Graceful Degradation
Wrap Sentry.init() in try/catch so an invalid DSN, network error, or SDK bug never crashes the app. Track initialization state with a boolean flag. Protect beforeSend callbacks with their own error boundary.
Create lib/sentry-safe.ts with initSentrySafe() and captureError(). See graceful-degradation.md for full implementation.
Key rules:
- Never let
Sentry.init() crash the process — wrap in try/catch, set sentryAvailable = false on failure
- Verify client creation with
Sentry.getClient() — invalid DSNs silently produce no client
- Always log errors locally as baseline before attempting Sentry capture
- Wrap user-supplied
beforeSend hooks in nested try/catch — return raw event on hook failure
Step 2 — Circuit Breaker for Sentry Outages
When Sentry is unreachable, continued attempts waste resources and add latency. Track consecutive failures and trip open after a threshold. After cooldown, enter half-open state and send a single probe.
Implement SentryCircuitBreaker class with closed/open/half-open states. See circuit-breaker-pattern.md for full implementation. Expose state via health-checks.md endpoint.
Key rules:
- Default: 5 failures to trip open, 60-second cooldown before half-open probe
- In open state, skip Sentry calls entirely and log to fallback
- On half-open success, reset to closed with zero failure count
- Expose
getStatus() for health check endpoints and monitoring dashboards
Step 3 — Offline Queue, Custom Transport, and Graceful Shutdown
Buffer events when network is unavailable and replay on reconnect. Use bounded file-based queue to survive restarts. Pair with signal handlers that flush via Sentry.close() before process exit.
Implement thre
Best practices for using Sentry SDK in TypeScript and Python.
ReadWriteEditGrep
Sentry SDK Patterns
Overview
Production patterns for @sentry/node (v8+) and sentry-sdk (Python 2.x+) covering scoped error context, breadcrumb strategies, event filtering with beforeSend, custom fingerprinting for issue grouping, and performance instrumentation with spans. All examples use real Sentry SDK APIs.
Prerequisites
- Sentry SDK v8+ installed (
@sentry/node, @sentry/react, or sentry-sdk)
SENTRY_DSN environment variable configured
- Familiarity with async/await (TypeScript) or context managers (Python)
Instructions
Step 1 -- Structured Error Context with Scopes
Use Sentry.withScope() (TypeScript) or sentry_sdk.new_scope() (Python) to attach context to individual events without leaking state across requests.
TypeScript -- Scoped error capture:
import * as Sentry from '@sentry/node';
type ErrorSeverity = 'low' | 'medium' | 'high' | 'critical';
interface ErrorOptions {
severity?: ErrorSeverity;
tags?: Record<string, string>;
context?: Record<string, unknown>;
user?: { id: string; email?: string };
fingerprint?: string[];
}
const SEVERITY_MAP: Record<ErrorSeverity, Sentry.SeverityLevel> = {
low: 'info',
medium: 'warning',
high: 'error',
critical: 'fatal',
};
export function captureError(error: Error, options: ErrorOptions = {}) {
Sentry.withScope((scope) => {
scope.setLevel(SEVERITY_MAP[options.severity || 'medium']);
if (options.tags) {
Object.entries(options.tags).forEach(([key, value]) => {
scope.setTag(key, value);
});
}
if (options.context) {
scope.setContext('app', options.context);
}
if (options.user) {
scope.setUser(options.user);
}
if (options.fingerprint) {
scope.setFingerprint(options.fingerprint);
}
Sentry.captureException(error);
});
}
Python -- Scoped error capture:
import sentry_sdk
def capture_error(error, severity="error", tags=None, context=None, user=None):
"""Capture exception with isolated scope context."""
with sentry_sdk.new_scope() as scope:
scope.set_level(severity)
if tags:
for key, value in tags.items():
scope.set_tag(key, value)
if context:
scope.set_context("app", context)
if user:
scope.set_user(user)
sentry_sdk.capture_exception(error)
Key rule: Never call Sentry.setTag() or sentry_sdk.set_tag() at the module level inside request handlers. Those mutate the glob
Configure Sentry security settings and data protection.
ReadWriteEditGrepBash(grep:*)Bash(curl:*)
Sentry Security Basics
Overview
Configure Sentry's security posture: PII scrubbing with beforeSend, built-in data scrubbing, IP anonymization, browser SDK URL filtering, DSN vs auth token handling, CSP reporting, and GDPR data deletion. Covers both client-side (SDK) and server-side (dashboard) controls.
Prerequisites
- Sentry project created with Owner or Admin role
@sentry/node >= 8.x or @sentry/browser >= 8.x installed (or sentry-sdk >= 2.x for Python)
- Compliance requirements identified (GDPR, SOC 2, HIPAA, CCPA)
- List of sensitive data patterns for your domain (PII fields, API keys, tokens)
Instructions
Step 1 — Understand DSN vs Auth Token Security
The DSN (Data Source Name) is a client-facing identifier — it tells the SDK where to send events. It is NOT a secret.
https://<public-key>@o<org-id>.ingest.us.sentry.io/<project-id>
- The DSN cannot read data, delete events, or modify settings
- It is safe to ship in client-side JavaScript bundles
- Restrict abuse via Allowed Domains (Project Settings > Client Keys > Configure)
Auth tokens ARE secrets — they grant API access to read/write/delete data:
# NEVER commit auth tokens — store in CI secrets or vault
# GitHub Actions: Settings > Secrets > SENTRY_AUTH_TOKEN
# GitLab CI: Settings > CI/CD > Variables (protected + masked)
# Generate tokens with MINIMAL scopes:
# CI releases: project:releases, org:read
# Issue triage: project:read, event:read
# NEVER: org:admin, member:admin in CI
# Rotate tokens quarterly — revoke unused tokens immediately
# Create separate tokens per pipeline (staging vs production)
Step 2 — Disable Default PII Collection
sendDefaultPii defaults to false — but always set it explicitly so intent is clear:
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
sendDefaultPii: false, // explicit: no IPs, no cookies, no user-agent
});
When sendDefaultPii: false (default):
- No IP addresses attached to events
- No cookies sent in request data
- No user-agent strings in request headers
- No request body data captured
- User context must be set manually via
Sentry.setUser()
# Python equivalent
import sentry_sdk
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
send_default_pii=False, # default, but be explicit
)
Step 3 — Client-Side PII Scrubbing with be
Upgrade Sentry SDK versions and migrate breaking API changes.
ReadWriteEditBash(npm:*)Bash(npx:*)Bash(pip:*)Bash(node:*)GrepGlob
Sentry Upgrade Migration
Detect installed Sentry SDK versions, identify breaking API changes, apply automated codemods, and verify the upgrade succeeds with test events and traces.
Current State
!npm list 2>/dev/null | command grep @sentry || echo 'No npm Sentry packages found' !pip show sentry-sdk 2>/dev/null | command grep -E '^(Name|Version)' || echo 'No Python sentry-sdk found' !node --version 2>/dev/null || echo 'Node.js not available'
Overview
Sentry SDK upgrades require careful handling of breaking API changes. The v7 to v8 JavaScript migration is the most impactful, removing the Hub pattern, replacing Transaction/Span APIs with startSpan(), converting class-based integrations to functions, and requiring ESM-first initialization. Python SDK v1 to v2 similarly replaces configure_scope() with get_current_scope(). This skill automates version detection, runs the official @sentry/migr8 codemod, applies manual fixes for patterns the codemod misses, and validates the upgrade with test events.
Prerequisites
- Current Sentry SDK version identified (run DCI above)
- Target version changelog reviewed
- Non-production environment for testing upgrades
- All
@sentry/* packages at the same major version before starting
- Node.js >= 18.19.0 or >= 20.6.0 for SDK v8 (ESM support required)
Instructions
Step 1. Identify Current SDK Version and Scan for Deprecated APIs
# JavaScript: list all Sentry packages and their versions
npm ls 2>/dev/null | command grep "@sentry/"
# Python: check installed version
pip show sentry-sdk 2>/dev/null
# Verify all @sentry/* packages are the same major version (critical!)
# Mixed versions cause runtime crashes
npm ls @sentry/core @sentry/node @sentry/browser @sentry/utils 2>/dev/null
Scan the codebase for deprecated patterns that need migration:
# Detect v7 Hub usage (removed in v8)
command grep -rn "getCurrentHub\|configureScope\|hub\.capture" src/ --include="*.ts" --include="*.js"
# Detect v7 Transaction API (replaced in v8)
command grep -rn "startTransaction\|\.startChild\|\.finish()" src/ --include="*.ts" --include="*.js"
# Detect class-based integrations (replaced in v8)
command grep -rn "new Sentry\.\|new BrowserTracing\|new Integrations\." src/ --include="*.ts" --include="*.js"
# Detect @sentry/tracing imports (package removed in v8)
command grep -rn "from '@sentry/tracing'" src/ --include="*.ts" --include="*.js"
# Python: detect v1 scope API (replaced in v2)
command grep -rn "configure_scope\|push_scope" src/ --inc
Ready to use sentry-pack?
|
|