openrouter-compliance-review
Review OpenRouter integration for regulatory compliance (SOC2, GDPR,
sentry-known-pitfalls
Identify and fix common Sentry SDK pitfalls that cause silent data loss,
Full skill instructions
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.
@sentry/node >= 8.x or @sentry/browser >= 8.xSentry.init() configuration.env, secrets manager, or CI/CD vars)# 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/
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://[email protected]/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__ });
sampleRate: 1.0 in Production100% 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,
});
flush() in Serverless/CLISentry 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);
});
beforeSend Returning null for All EventsMissing 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
},
});
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"
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;
}
}
environment TagWithout 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';
}
@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
429 Too Many RequestsWhen 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:
// Client-side circuit breaker for resilience
let sentryBackoff = 0;
Sentry.init({
beforeSend(event) {
if (Date.now() < sentryBackoff) return null;
return event;
},
});
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.
See audit script for a bash script that checks all 10 pitfalls in one pass.
beforeSend returns event on all pathsenvironment and release properly configured| 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 |
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.
Review OpenRouter integration for regulatory compliance (SOC2, GDPR,
Data synchronization, ETL patterns, and data management for MaintainX.
Execute Groq primary workflow: chat completions with tool use and JSON
Validate CSRF protection implementations for security gaps. Use when
Configure this skill should be used when the user asks about "API contract",
Execute Ideogram incident response with triage, mitigation, and postmortem.
Execute create, select, and transform features to improve machine learning
Reusable patterns for the Gamma REST API (no SDK exists).
Apply production-ready Deepgram SDK patterns for TypeScript and Python.
Migrate to OpenRouter from direct provider APIs or upgrade between SDK/model
Diagnose and fix common OpenRouter API errors. Use when encountering
Optimize Linear API usage, reduce unnecessary calls, and maximize
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience