Claude-code-plugins-plus-skills sentry-debug-bundle
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/sentry-pack/skills/sentry-debug-bundle" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-skills-sentry-debug-bundle && rm -rf "$T"
plugins/saas-packs/sentry-pack/skills/sentry-debug-bundle/SKILL.mdSentry 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
, or@sentry/react
for Python)sentry-sdk
environment variable set (or DSN configured in application code)SENTRY_DSN- For API checks:
withSENTRY_AUTH_TOKEN
scope (generate token)project:read - Optional:
installed for source map diagnostics andsentry-cli
testssend-event
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.profilesSampleRate ?? '(not set)', send_default_pii: opts.sendDefaultPii ?? false, max_breadcrumbs: opts.maxBreadcrumbs ?? 100, before_send: typeof opts.beforeSend === 'function' ? 'CONFIGURED' : 'none', before_send_transaction: typeof opts.beforeSendTransaction === 'function' ? 'CONFIGURED' : 'none', before_breadcrumb: typeof opts.beforeBreadcrumb === 'function' ? 'CONFIGURED' : 'none', integrations: client.getOptions().integrations?.map(i => i.name) ?? [], transport: opts.transport ? 'custom' : 'default', }; console.log(JSON.stringify(diagnostics, null, 2));
Extract runtime configuration (Python):
import sentry_sdk from sentry_sdk import Hub client = Hub.current.client if not client: print("ERROR: Sentry client not initialized") exit(1) opts = client.options print(f"SDK version: {sentry_sdk.VERSION}") print(f"DSN configured: {bool(opts.get('dsn'))}") print(f"Environment: {opts.get('environment', '(default)')}") print(f"Release: {opts.get('release', '(auto-detect)')}") print(f"Debug: {opts.get('debug', False)}") print(f"Sample rate: {opts.get('sample_rate', 1.0)}") print(f"Traces sample rate:{opts.get('traces_sample_rate', '(not set)')}") print(f"Send default PII: {opts.get('send_default_pii', False)}") print(f"before_send: {'CONFIGURED' if opts.get('before_send') else 'none'}") print(f"before_breadcrumb: {'CONFIGURED' if opts.get('before_breadcrumb') else 'none'}") print(f"Integrations: {[i.identifier for i in client.integrations.values()]}")
Key check: If
is CONFIGURED, inspect the function — abeforeSendthat returnsbeforeSendwill silently drop every event.null
Step 2 — Verify DSN Connectivity and Sentry Service Status
Confirm the application can reach Sentry's ingest endpoint and that Sentry itself is operational.
Test DSN reachability:
# Test the Sentry API root (should return HTTP 200) curl -s -o /dev/null -w "sentry.io API: HTTP %{http_code} (%{time_total}s)\n" \ https://sentry.io/api/0/ # Test the ingest endpoint derived from your DSN # DSN format: https://<PUBLIC_KEY>@o<ORG_ID>.ingest.sentry.io/<PROJECT_ID> # Extract host from DSN and test the envelope endpoint curl -s -o /dev/null -w "Ingest endpoint: HTTP %{http_code} (%{time_total}s)\n" \ "https://o0.ingest.sentry.io/api/0/envelope/" # DNS resolution check dig +short o0.ingest.sentry.io 2>/dev/null || nslookup o0.ingest.sentry.io # Check for proxy/firewall interference curl -v https://sentry.io/api/0/ 2>&1 | grep -iE 'proxy|blocked|forbidden|connect'
Check Sentry service status:
Visit https://status.sentry.io or:
# Programmatic status check curl -s https://status.sentry.io/api/v2/status.json | python3 -c " import sys, json d = json.load(sys.stdin) print(f\"Sentry Status: {d['status']['description']}\") print(f\"Updated: {d['page']['updated_at']}\") "
Verify auth token and project access (requires
):SENTRY_AUTH_TOKEN
# Check token validity and list accessible projects curl -s -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \ https://sentry.io/api/0/projects/ | python3 -c " import sys, json projects = json.load(sys.stdin) if isinstance(projects, dict) and 'detail' in projects: print(f'Auth error: {projects[\"detail\"]}') else: for p in projects[:10]: print(f\" {p['organization']['slug']}/{p['slug']} (platform: {p.get('platform', 'N/A')})\")" # sentry-cli auth check sentry-cli info 2>/dev/null || echo "sentry-cli not authenticated — run: sentry-cli login"
Step 3 — Test Event Capture, Verify Delivery, and Generate Report
Send a diagnostic test event, confirm it arrives in Sentry, and produce the final debug bundle report.
Send test event via sentry-cli:
# Quick test — sends a test message event sentry-cli send-event -m "diagnostic test from debug-bundle $(date -u +%Y-%m-%dT%H:%M:%SZ)"
Send test event programmatically (Node.js):
import * as Sentry from '@sentry/node'; Sentry.init({ dsn: process.env.SENTRY_DSN, debug: true, // Enables console logging of SDK internals }); const eventId = Sentry.captureMessage('sentry-debug-bundle diagnostic test', 'info'); console.log(`Test event ID: ${eventId}`); console.log(`View at: https://sentry.io/organizations/YOUR_ORG/issues/?query=${eventId}`); // CRITICAL: Node.js will exit before async transport completes without flush const flushed = await Sentry.flush(10000); console.log(`Flush: ${flushed ? 'SUCCESS — event delivered' : 'TIMEOUT — event may not have been sent'}`); if (!flushed) { console.error('Flush timeout. Possible causes:'); console.error(' - Network blocking outbound HTTPS to sentry.io'); console.error(' - DSN is invalid or project has been deleted'); console.error(' - Rate limit exceeded (HTTP 429)'); }
Send test event programmatically (Python):
import sentry_sdk import time sentry_sdk.init(dsn="YOUR_DSN", debug=True) event_id = sentry_sdk.capture_message("sentry-debug-bundle diagnostic test", level="info") print(f"Test event ID: {event_id}") # Python SDK flushes automatically on exit, but explicit flush is safer sentry_sdk.flush(timeout=10) print("Flush complete — check Sentry dashboard for event")
Generate the debug bundle report:
#!/bin/bash set -euo pipefail REPORT="sentry-debug-$(date +%Y%m%d-%H%M%S).md" cat > "$REPORT" << 'HEADER' # Sentry Debug Bundle HEADER cat >> "$REPORT" << EOF **Generated:** $(date -u +"%Y-%m-%dT%H:%M:%SZ") **Node.js:** $(node --version 2>/dev/null || echo N/A) **Python:** $(python3 --version 2>/dev/null || echo N/A) **OS:** $(uname -srm) **sentry-cli:** $(sentry-cli --version 2>/dev/null || echo 'not installed') ## SDK Packages \`\`\` $(npm list 2>/dev/null | grep -i sentry || echo "No npm Sentry packages") $(pip show sentry-sdk 2>/dev/null | grep -E '^(Name|Version|Location)' || echo "No pip sentry-sdk") \`\`\` ## Environment Variables (sanitized) | Variable | Status | |----------|--------| | SENTRY_DSN | $([ -n "${SENTRY_DSN:-}" ] && echo "SET (\`$(echo "$SENTRY_DSN" | sed 's|//[^@]*@|//***@|')\`)" || echo "NOT SET") | | SENTRY_ORG | ${SENTRY_ORG:-NOT SET} | | SENTRY_PROJECT | ${SENTRY_PROJECT:-NOT SET} | | SENTRY_AUTH_TOKEN | $([ -n "${SENTRY_AUTH_TOKEN:-}" ] && echo "SET (${#SENTRY_AUTH_TOKEN} chars)" || echo "NOT SET") | | SENTRY_RELEASE | ${SENTRY_RELEASE:-NOT SET} | | SENTRY_ENVIRONMENT | ${SENTRY_ENVIRONMENT:-NOT SET} | | NODE_ENV | ${NODE_ENV:-NOT SET} | ## Network Connectivity $(curl -s -o /dev/null -w "- sentry.io API: HTTP %{http_code} (%{time_total}s)" https://sentry.io/api/0/ 2>/dev/null || echo "- sentry.io: UNREACHABLE") $(curl -s -o /dev/null -w "\n- Ingest endpoint: HTTP %{http_code} (%{time_total}s)" https://o0.ingest.sentry.io/api/0/envelope/ 2>/dev/null || echo "- Ingest: UNREACHABLE") ## Sentry Status $(curl -s https://status.sentry.io/api/v2/status.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(f\"- Status: {d['status']['description']}\")" 2>/dev/null || echo "- Status: Could not fetch") ## CLI Authentication Status \`\`\` $(sentry-cli info 2>/dev/null || echo "sentry-cli not authenticated — run: sentry-cli login") \`\`\` ## Source Map Artifacts \`\`\` $(sentry-cli releases files "${SENTRY_RELEASE:-unknown}" list 2>/dev/null || echo "No release artifacts found (set SENTRY_RELEASE)") \`\`\` EOF echo "Debug bundle saved to: $REPORT" echo "Attach this file to your Sentry support ticket at https://sentry.io/support/"
Output
The debug bundle produces:
- SDK inventory — all
or@sentry/*
versions with mismatch detectionsentry-sdk - Configuration snapshot — DSN (redacted), environment, release, sample rates, hooks status
- Connectivity report — HTTP status and latency to
API and ingest endpointssentry.io - Service status — current Sentry platform health from status.sentry.io
- Test event confirmation — event ID with flush result (SUCCESS or TIMEOUT)
- Markdown report file —
ready to attach to support ticketssentry-debug-YYYYMMDD-HHMMSS.md
Error Handling
| Error | Cause | Solution |
|---|---|---|
| not called or called after diagnostic code | Ensure runs at application entry point before any capture calls |
| Network blocking outbound HTTPS to | Check firewall rules, corporate proxy, VPN — allow outbound 443 to |
reports no auth | Token not set or expired | Run or set (generate) |
Package version mismatch ( at different versions) | Partial upgrade or transitive dependency conflict | Align all packages to the same version: and run |
shows no match | does not match the stack trace URLs | Compare the in your error event's stack frame with the used during upload |
Events dropped by | Hook returns for matching events | Log inside to verify: |
| DSN returns HTTP 401 / 403 | Project deleted, DSN revoked, or wrong organization | Verify DSN at Settings > Projects > Client Keys in the Sentry dashboard |
| Organization or project rate limit exceeded | Check quotas at Settings > Subscription, reduce /, or use to filter noise |
| Process exits before events sent (Node.js) | No before | Always call before exiting; in serverless, use the platform's |
Examples
TypeScript — Full Diagnostic Script
// scripts/sentry-diagnostics.ts import * as Sentry from '@sentry/node'; async function runDiagnostics() { // 1. Check SDK is initialized const client = Sentry.getClient(); if (!client) { console.error('[FAIL] Sentry client not initialized'); console.error(' Ensure Sentry.init({ dsn: "..." }) is called before this script'); return; } console.log(`[OK] SDK version: ${Sentry.SDK_VERSION}`); // 2. Check configuration const opts = client.getOptions(); console.log(`[OK] DSN configured: ${!!opts.dsn}`); console.log(`[INFO] Environment: ${opts.environment ?? '(default)'}`); console.log(`[INFO] Release: ${opts.release ?? '(auto-detect)'}`); console.log(`[INFO] Debug mode: ${opts.debug ?? false}`); console.log(`[INFO] Sample rate: ${opts.sampleRate ?? 1.0}`); console.log(`[INFO] Traces sample rate: ${opts.tracesSampleRate ?? '(not set)'}`); console.log(`[INFO] beforeSend: ${typeof opts.beforeSend === 'function' ? 'CONFIGURED' : 'none'}`); // 3. List active integrations const integrations = opts.integrations?.map(i => i.name) ?? []; console.log(`[INFO] Integrations (${integrations.length}): ${integrations.join(', ')}`); // 4. Send test event const eventId = Sentry.captureMessage('sentry-diagnostics test event', 'info'); console.log(`[INFO] Test event ID: ${eventId}`); // 5. Flush and verify const flushed = await Sentry.flush(10000); if (flushed) { console.log('[OK] Flush succeeded — event delivered to Sentry'); } else { console.error('[FAIL] Flush timed out — check network connectivity to Sentry'); } } runDiagnostics().catch(err => console.error('[FAIL] Diagnostic error:', err));
Python — Full Diagnostic Script
# scripts/sentry_diagnostics.py import sentry_sdk from sentry_sdk import Hub import urllib.request import json import sys def run_diagnostics(): print("=== Sentry Debug Bundle (Python) ===\n") # 1. SDK version print(f"SDK version: {sentry_sdk.VERSION}") # 2. Client check client = Hub.current.client if not client: print("[FAIL] Sentry client not initialized") print(" Call sentry_sdk.init(dsn='...') before running diagnostics") sys.exit(1) print("[OK] Client initialized") # 3. Configuration opts = client.options print(f"[INFO] DSN configured: {bool(opts.get('dsn'))}") print(f"[INFO] Environment: {opts.get('environment', '(default)')}") print(f"[INFO] Release: {opts.get('release', '(auto-detect)')}") print(f"[INFO] Debug: {opts.get('debug', False)}") print(f"[INFO] Sample rate: {opts.get('sample_rate', 1.0)}") print(f"[INFO] Traces sample rate: {opts.get('traces_sample_rate', '(not set)')}") print(f"[INFO] before_send: {'CONFIGURED' if opts.get('before_send') else 'none'}") print(f"[INFO] before_breadcrumb: {'CONFIGURED' if opts.get('before_breadcrumb') else 'none'}") # 4. Integrations integrations = [i.identifier for i in client.integrations.values()] print(f"[INFO] Integrations ({len(integrations)}): {', '.join(integrations)}") # 5. Network connectivity try: req = urllib.request.urlopen("https://sentry.io/api/0/", timeout=5) print(f"[OK] sentry.io reachable (HTTP {req.status})") except Exception as e: print(f"[FAIL] sentry.io unreachable: {e}") # 6. Service status try: req = urllib.request.urlopen("https://status.sentry.io/api/v2/status.json", timeout=5) data = json.loads(req.read()) print(f"[INFO] Sentry status: {data['status']['description']}") except Exception: print("[WARN] Could not fetch Sentry status") # 7. Test event event_id = sentry_sdk.capture_message("sentry-diagnostics test event", level="info") print(f"[INFO] Test event ID: {event_id}") # 8. Flush sentry_sdk.flush(timeout=10) print("[OK] Flush complete") if __name__ == "__main__": run_diagnostics()
Resources
- Sentry Troubleshooting Guide (JavaScript) — official SDK debugging steps
- Sentry Troubleshooting Guide (Python) — Python-specific diagnostics
- Source Maps Troubleshooting —
and URL prefix debuggingsourcemaps explain - sentry-cli Reference — CLI installation, auth,
,send-event
commandssourcemaps - Sentry Status Page — real-time platform health
- Sentry Support — submit tickets with your debug bundle attached
- sentry-javascript GitHub Issues — known bugs and community reports
Next Steps
After collecting the debug bundle:
- Events missing? Check
hook — add logging to confirm events are not being droppedbeforeSend - Source maps broken? Run
to diagnose URL prefix mismatchessentry-cli sourcemaps explain --org ORG --project PROJ EVENT_ID - Performance data missing? Verify
is non-zero and the instrumentation integration is activetracesSampleRate - Rate limited? Review org quotas at Settings > Subscription and reduce sample rates
- Need deeper tracing? Enable
indebug: true
to see full SDK lifecycle in consoleSentry.init() - Ready to file a ticket? Attach the generated
file to your request at sentry.io/supportsentry-debug-*.md