Sentry Integration skill for Codex
Readable stack traces from every production build. Codex places Sentry init where it actually instruments the app, tags every event with release and environment, and uploads source maps for the exact build that ships so traces show original code. CI creates releases with commits and deploys, sampling keeps span and Replay usage predictable, and auth headers and tokens are scrubbed before events leave.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- sentry-integration Installs to ~/.agents/skills/sentry-integration/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install sentry-integration The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project sentry-integration Installs to .agents/skills/sentry-integration/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/sentry-integration.zipunzip -o sentry-integration.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) sentry-integration PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $sentry-integration, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Sets up Sentry SDKs correctly in JavaScript, Next.js, Node and Python apps - init placement, environments, releases tied to commits, source map upload with debug IDs via the Vite, webpack or Next.js plugins or sentry-cli, sampling for traces and Replay, PII scrubbing, and CI release and deploy steps. Use when adding Sentry to a project, stack traces show minified code, errors lack release or environment, events are missing, the quota is being burned, or CI should create Sentry releases.
Use it when
- Adding a Sentry SDK to a frontend, Node or Python project
- Production stack traces in Sentry show minified bundles
- Events are missing release, environment or user context
- Sentry quota is being consumed faster than expected
Use something else when
- Sentry is set up and you need to triage, group and assign issues: use sentry-error-tracking
- You want vendor-neutral tracing and metrics: use opentelemetry
How to check the result
A smoke-test error from a production build appears with the right release and environment and its top frame points at original source, while .map files return 404 publicly.
The mistake it prevents
Initialising Sentry after the server framework and database client are imported, so automatic tracing never attaches.
Done well means: the SDK initialises before anything else runs, every event carries release and
environment, production stack traces are readable because source maps uploaded for that exact
build, sampling keeps cost predictable, and no secrets or unnecessary personal data leave the app.
Inspect first
- Read
AGENTS.md; thenrg -n "@sentry/|sentry_sdk|SENTRY_" --glob '!node_modules'. - Note the SDK major version in the lockfile and the framework (Next.js, Vite SPA, Node server,
Django/FastAPI). Mixed
@sentry/*versions in one app cause runtime errors; align them. - Find the build output directory, how the app is versioned (git SHA, semver tag) and the CI system.
- Confirm DSN, org slug, project slug, and that an auth token exists as a CI secret
(
SENTRY_AUTH_TOKEN, organization token with release and source map permissions).
The setup wizard (npx @sentry/wizard@latest -i nextjs, or -i sourcemaps) writes most of this
for you but needs network and an interactive login; in a sandbox without network, write the files
by hand following the sections below.
Where init goes
| Runtime | File and rule |
|---|---|
| Next.js (App Router) | instrumentation-client.ts (browser), sentry.server.config.ts and sentry.edge.config.ts imported from instrumentation.ts register(); wrap next.config with withSentryConfig |
| Vite / SPA | First import in main.tsx, before the app renders |
| Node (ESM) | instrument.mjs loaded with node --import ./instrument.mjs server.mjs so auto-instrumentation patches modules before they load |
| Node (CJS) | require('./instrument') as the first line of the entry file |
| Python | sentry_sdk.init() at process start, before the framework app object is created |
// instrument.mjs (Node) or the browser init file
import * as Sentry from '@sentry/node'; // @sentry/react, @sentry/nextjs, ...
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.SENTRY_ENVIRONMENT ?? 'development',
release: process.env.SENTRY_RELEASE, // build plugins inject this automatically
sendDefaultPii: false,
tracesSampleRate: 0.1,
beforeSend(event) {
if (event.request?.headers) delete event.request.headers['authorization'];
return event;
},
});
import sentry_sdk
sentry_sdk.init(
dsn=os.environ.get("SENTRY_DSN"),
environment=os.environ.get("SENTRY_ENVIRONMENT", "development"),
release=os.environ.get("SENTRY_RELEASE"),
traces_sample_rate=0.1,
send_default_pii=False,
)
Django, Flask, FastAPI, Celery and most popular libraries are auto-detected; add integrations explicitly only to change options.
Sampling and cost
| Signal | Starting point | Notes |
|---|---|---|
| Errors | 100% (sampleRate: 1) | Drop noise with ignoreErrors / denyUrls, not by sampling |
| Traces | 0.05-0.2, or a tracesSampler that keeps 100% of checkout/login and drops health checks | Spans are billed |
| Session Replay | replaysSessionSampleRate: 0-0.1, replaysOnErrorSampleRate: 1.0 | Replay masks all text and inputs by default; keep it that way |
| Profiles | Only when actively investigating performance |
Set inbound filters and spike protection in the project settings too; changing org billing or quotas is the user’s decision.
Source maps
Source maps are matched to minified files by debug ID. Upload them for every production build and do not serve them publicly.
Vite:
// vite.config.ts
import { sentryVitePlugin } from '@sentry/vite-plugin';
export default defineConfig({
build: { sourcemap: 'hidden' }, // generate maps, no sourceMappingURL comment
plugins: [
react(),
sentryVitePlugin({ // keep last
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
sourcemaps: { filesToDeleteAfterUpload: ['./dist/**/*.map'] },
}),
],
});
Next.js: withSentryConfig(nextConfig, { org, project, authToken: process.env.SENTRY_AUTH_TOKEN, widenClientFileUpload: true, silent: !process.env.CI }).
Webpack and esbuild have equivalent @sentry/webpack-plugin and @sentry/esbuild-plugin.
Any other bundler, or a prebuilt dist/:
npx @sentry/cli sourcemaps inject ./dist
npx @sentry/cli sourcemaps upload --org "$SENTRY_ORG" --project "$SENTRY_PROJECT" ./dist
Deploy the files that went through inject; if the build runs again after upload, debug IDs no
longer match.
Releases and deploys in CI
export SENTRY_RELEASE="$(git rev-parse HEAD)" # same value passed to the build and to Sentry.init
npx @sentry/cli releases new "$SENTRY_RELEASE"
npx @sentry/cli releases set-commits "$SENTRY_RELEASE" --auto
# build + source map upload happen here
npx @sentry/cli releases finalize "$SENTRY_RELEASE"
npx @sentry/cli deploys new --release "$SENTRY_RELEASE" -e production
set-commits --autoneeds the repository integration configured in Sentry and full git history in CI (fetch-depth: 0on GitHub Actions); otherwise suspect commits stay empty.- Mark the deploy only after the production deploy succeeds. Use one release value across frontend and backend only if they deploy together.
- Releases and deploys are visible to the whole org; creating them from a local machine against the production project should be confirmed with the user.
Context that makes events actionable
Sentry.setUser({ id: user.id })- an internal ID, not email, unless the privacy policy allows it.Sentry.setTag('tenant', tenantId)for searchable dimensions; keep tag cardinality modest.Sentry.captureException(err, { extra: { orderId } })where you catch and handle errors that still matter. Do not capture expected validation errors.- Wrap background jobs and cron entries; use Cron Monitors (
Sentry.withMonitor) for scheduled jobs. - Browser apps blocked by ad blockers: route through your own domain (
tunneloption, ortunnelRoutein the Next.js config).
Verification
- Trigger a test error in a production-like build (
throw new Error('sentry smoke ' + Date.now())behind a debug route or flag) and find it in Sentry within a minute. - The event shows the expected
releaseandenvironment, and the top frame is original source with file names and line numbers, notmain.3f9a.js:1:20431. - If frames are minified, open the issue’s source map troubleshooting details: usually a missing debug ID (build not injected), a map uploaded for another build, or maps deleted before upload.
-
.mapfiles return 404 from the production host. - Authorization headers, cookies and tokens are absent from the event payload.
- Remove the smoke-test route afterwards.
Gotchas
- Initialising Sentry after importing
express,pgorhttpsilently disables their tracing. SENTRY_AUTH_TOKENin a client bundle (viaNEXT_PUBLIC_orVITE_prefix) leaks it; it belongs only in CI env. The DSN is public by design.tracesSampleRate: 1.0copied from docs into production burns the span quota in hours.- Running the build twice in CI (once for tests, once for deploy) uploads maps for the wrong artifact.
- Different
releasestrings in frontend init and CLI upload break release health and suspect commits.
Output
Report: SDKs and versions, init file locations, release naming, source map method, sampling rates, CI steps added, scrubbing rules, and the smoke-test event link or ID.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Sentry Integration"
short_description: "Readable stack traces from every production build"
default_prompt: "$sentry-integration Add Sentry to our Next.js app with source maps and release tracking" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.