skills/sentry-cloudflare-sdk/SKILL.md
Full Sentry SDK setup for Cloudflare Workers and Pages. Use when asked to "add Sentry to Cloudflare Workers", "install @sentry/cloudflare", or configure error monitoring, tracing, logging, crons, or AI monitoring for Cloudflare Workers, Pages, Durable Objects, Queues, Workflows, or Hono on Cloudflare.
npx skillsauth add getsentry/sentry-for-claude sentry-cloudflare-sdkInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
All Skills > SDK Setup > Cloudflare SDK
Opinionated wizard that scans your Cloudflare project and guides you through complete Sentry setup for Workers, Pages, Durable Objects, Queues, Workflows, and Hono.
@sentry/cloudflarewithSentry, sentryPagesPlugin, instrumentDurableObjectWithSentry, or instrumentD1WithSentryNote: SDK versions and APIs below reflect current Sentry docs at time of writing (
@sentry/cloudflarev10.55.0). Always verify against docs.sentry.io/platforms/javascript/guides/cloudflare/ before implementing.
Run these commands to understand the project before making any recommendations:
# Detect Cloudflare project
ls wrangler.toml wrangler.jsonc wrangler.json 2>/dev/null
# Detect existing Sentry
cat package.json 2>/dev/null | grep -E '"@sentry/'
# Detect project type (Workers vs Pages)
ls functions/ functions/_middleware.js functions/_middleware.ts 2>/dev/null && echo "Pages detected"
cat wrangler.toml 2>/dev/null | grep -E 'main|pages_build_output_dir'
# Detect framework
cat package.json 2>/dev/null | grep -E '"hono"|"remix"|"astro"|"svelte"'
# Detect Durable Objects
cat wrangler.toml 2>/dev/null | grep -i 'durable_objects'
# Detect D1 databases
cat wrangler.toml 2>/dev/null | grep -i 'd1_databases'
# Detect Queues
cat wrangler.toml 2>/dev/null | grep -i 'queues'
# Detect Workflows
cat wrangler.toml 2>/dev/null | grep -i 'workflows'
# Detect Scheduled handlers (cron triggers)
cat wrangler.toml 2>/dev/null | grep -i 'crons\|triggers'
# Detect compatibility flags
cat wrangler.toml 2>/dev/null | grep -i 'compatibility_flags'
cat wrangler.jsonc 2>/dev/null | grep -i 'compatibility_flags'
# Detect AI/LLM libraries
cat package.json 2>/dev/null | grep -E '"openai"|"@anthropic-ai"|"ai"|"@google/generative-ai"|"@langchain"'
# Detect logging libraries
cat package.json 2>/dev/null | grep -E '"pino"|"winston"'
# Check for companion frontend
ls frontend/ web/ client/ 2>/dev/null
cat package.json 2>/dev/null | grep -E '"react"|"vue"|"svelte"|"next"'
What to determine:
| Question | Impact |
|----------|--------|
| Workers or Pages? | Determines wrapper: withSentry vs sentryPagesPlugin |
| Hono framework? | Recommend standalone @sentry/hono package (v10.55.0+) for cleaner integration |
| @sentry/cloudflare already installed? | Skip install, go to feature config |
| Durable Objects configured? | Recommend instrumentDurableObjectWithSentry |
| D1 databases bound? | Recommend instrumentD1WithSentry |
| Queues configured? | withSentry auto-instruments queue handlers |
| Workflows configured? | Recommend instrumentWorkflowWithSentry |
| Cron triggers configured? | withSentry auto-instruments scheduled handlers; recommend Crons monitoring |
| nodejs_als or nodejs_compat flag set? | Required — SDK needs AsyncLocalStorage |
| AI/LLM libraries? | Recommend AI Monitoring integrations |
| Companion frontend? | Trigger Phase 4 cross-link |
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage):
Optional (enhanced observability):
Sentry.logger.*; recommend when log search is neededRecommendation logic:
| Feature | Recommend when... |
|---------|------------------|
| Error Monitoring | Always — non-negotiable baseline |
| Tracing | Always — HTTP request tracing and outbound fetch are high-value |
| Logging | App needs structured log search or log-to-trace correlation |
| Crons | Cron triggers configured in wrangler.toml |
| D1 Instrumentation | D1 database bindings present |
| Durable Objects | Durable Object bindings configured |
| Workflows | Workflow bindings configured |
| AI Monitoring | App uses Vercel AI SDK, OpenAI, Anthropic, or LangChain |
| Metrics | App needs custom counters, gauges, or distributions |
Propose: "I recommend setting up Error Monitoring + Tracing. Want me to also add D1 instrumentation and Crons monitoring?"
You need to run this yourself — the wizard opens a browser for login and requires interactive input that the agent can't handle. Copy-paste into your terminal:
npx @sentry/wizard@latest -i sourcemapsThis sets up source map uploading so your production stack traces show readable code. It does not set up the SDK initialization — you still need to follow Option 2 below for the actual SDK setup.
Once it finishes, continue with Option 2 for SDK setup.
Note: Unlike framework SDKs (Next.js, SvelteKit), there is no Cloudflare-specific wizard integration. The
sourcemapswizard only handles source map upload configuration.
The SDK requires AsyncLocalStorage. Add one of these flags to your Wrangler config:
wrangler.toml:
compatibility_flags = ["nodejs_als"]
# or: compatibility_flags = ["nodejs_compat"]
wrangler.jsonc:
{
"compatibility_flags": ["nodejs_als"]
}
nodejs_alsis lighter — it only enablesAsyncLocalStorage. Usenodejs_compatif your code also needs other Node.js APIs.
npm install @sentry/cloudflare
Wrap your handler with withSentry. This automatically instruments fetch, scheduled, queue, email, and tail handlers:
import * as Sentry from "@sentry/cloudflare";
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.SENTRY_DSN,
sendDefaultPii: true,
tracesSampleRate: 1.0,
enableLogs: true,
}),
{
async fetch(request, env, ctx) {
return new Response("Hello World!");
},
} satisfies ExportedHandler<Env>,
);
Key points:
env — use this to read secrets like SENTRY_DSNenv automatically (see Environment Variables)withSentry wraps all exported handlers — you do not need separate wrappers for scheduled, queue, etc.Use sentryPagesPlugin as middleware:
// functions/_middleware.ts
import * as Sentry from "@sentry/cloudflare";
export const onRequest = Sentry.sentryPagesPlugin((context) => ({
dsn: context.env.SENTRY_DSN,
sendDefaultPii: true,
tracesSampleRate: 1.0,
enableLogs: true,
}));
Chaining multiple middlewares:
import * as Sentry from "@sentry/cloudflare";
export const onRequest = [
// Sentry must be first
Sentry.sentryPagesPlugin((context) => ({
dsn: context.env.SENTRY_DSN,
tracesSampleRate: 1.0,
})),
// Add more middlewares here
];
Using wrapRequestHandler directly (for frameworks like SvelteKit on Cloudflare Pages):
import * as Sentry from "@sentry/cloudflare";
export const handle = ({ event, resolve }) => {
return Sentry.wrapRequestHandler(
{
options: {
dsn: event.platform.env.SENTRY_DSN,
tracesSampleRate: 1.0,
},
request: event.request,
context: event.platform.ctx,
},
() => resolve(event),
);
};
Recommended (v10.55.0+): Use the standalone @sentry/hono package for Hono apps:
npm install @sentry/hono @sentry/cloudflare
The @sentry/cloudflare package is a peer dependency and must stay in sync with @sentry/hono.
import { Hono } from "hono";
import { sentry } from "@sentry/hono/cloudflare";
type Bindings = { SENTRY_DSN: string };
const app = new Hono<{ Bindings: Bindings }>();
// Initialize Sentry middleware as early as possible
app.use(
sentry(app, (env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
})),
);
app.get("/", (ctx) => ctx.json({ message: "Hello" }));
app.get("/error", () => {
throw new Error("Test error");
});
export default app;
The sentry() middleware automatically captures errors and creates transaction spans with route patterns.
Legacy approach (deprecated): Using @sentry/cloudflare with withSentry still works, but honoIntegration is deprecated:
import { Hono } from "hono";
import * as Sentry from "@sentry/cloudflare";
const app = new Hono();
app.get("/", (ctx) => ctx.json({ message: "Hello" }));
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
}),
app,
);
Store your DSN as a Cloudflare secret — do not hardcode it:
# Local development: add to .dev.vars
echo 'SENTRY_DSN="https://[email protected]/0"' >> .dev.vars
# Production: set as a secret
npx wrangler secret put SENTRY_DSN
Add the binding to your Env type:
interface Env {
SENTRY_DSN: string;
// ... other bindings
}
Source maps make production stack traces readable. Without them, you see minified/bundled code.
Step 1: Generate a Sentry auth token
Go to sentry.io/settings/auth-tokens/ and create a token with project:releases and org:read scopes.
Step 2: Install the Sentry Vite plugin (most Cloudflare projects use Vite via Wrangler):
npm install @sentry/vite-plugin --save-dev
Step 3: Configure vite.config.ts (if your project has one):
import { defineConfig } from "vite";
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig({
build: {
sourcemap: true,
},
plugins: [
sentryVitePlugin({
org: "___ORG_SLUG___",
project: "___PROJECT_SLUG___",
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
],
});
Step 4: Set environment variables in CI
SENTRY_AUTH_TOKEN=sntrys_eyJ...
SENTRY_ORG=my-org
SENTRY_PROJECT=my-project
Step 5: Add to .gitignore
.dev.vars
.env.sentry-build-plugin
The SDK can automatically detect the release version via Cloudflare's version metadata binding:
wrangler.toml:
[version_metadata]
binding = "CF_VERSION_METADATA"
Release priority (highest to lowest):
release option passed to Sentry.init()SENTRY_RELEASE environment variableCF_VERSION_METADATA.id bindingLoad the corresponding reference file and follow its steps:
| Feature | Reference file | Load when... |
|---------|---------------|-------------|
| Error Monitoring | references/error-monitoring.md | Always (baseline) — unhandled exceptions, manual capture, scopes, enrichment |
| Tracing | references/tracing.md | HTTP request tracing, outbound fetch spans, D1 query spans, distributed tracing |
| Logging | references/logging.md | Structured logs via Sentry.logger.*, log-to-trace correlation |
| Crons | references/crons.md | Scheduled handler monitoring, withMonitor, check-in API |
| Durable Objects | references/durable-objects.md | Instrument Durable Object classes for error capture and spans |
For each feature: read the reference file, follow its steps exactly, and verify before moving on.
After setup, verify Sentry is working:
// Add temporarily to your fetch handler, then remove
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
}),
{
async fetch(request, env, ctx) {
throw new Error("Sentry test error — delete me");
},
} satisfies ExportedHandler<Env>,
);
Deploy and trigger the route, then check your Sentry Issues dashboard — the error should appear within ~30 seconds.
Verification checklist:
| Check | How |
|-------|-----|
| Errors captured | Throw in a fetch handler, verify in Sentry |
| Tracing working | Check Performance tab for HTTP spans |
| Source maps working | Check stack trace shows readable file/line names |
| D1 spans (if configured) | Run a D1 query, check for db.query spans |
| Scheduled monitoring (if configured) | Trigger a cron, check Crons dashboard |
Sentry.init() Options| Option | Type | Default | Notes |
|--------|------|---------|-------|
| dsn | string | — | Required. Read from env.SENTRY_DSN automatically if not set |
| tracesSampleRate | number | — | 0–1; 1.0 in dev, lower in prod recommended |
| tracesSampler | function | — | Dynamic sampling function; mutually exclusive with tracesSampleRate |
| sendDefaultPii | boolean | false | Include request headers and cookies in events |
| enableLogs | boolean | false | Enable Sentry Logs product |
| environment | string | auto | Read from env.SENTRY_ENVIRONMENT if not set |
| release | string | auto | Detected from CF_VERSION_METADATA.id or SENTRY_RELEASE |
| debug | boolean | false | Read from env.SENTRY_DEBUG if not set. Log SDK activity to console |
| tunnel | string | — | Read from env.SENTRY_TUNNEL if not set |
| beforeSend | function | — | Filter/modify error events before sending |
| beforeSendTransaction | function | — | Filter/modify transaction events before sending |
| beforeSendLog | function | — | Filter/modify log entries before sending |
| tracePropagationTargets | (string\|RegExp)[] | all URLs | Control which outbound requests get trace headers |
| skipOpenTelemetrySetup | boolean | false | Opt-out of OpenTelemetry compatibility tracer |
| instrumentPrototypeMethods | boolean \| string[] | false | Durable Object: instrument prototype methods for RPC spans |
env)The SDK reads these from the Cloudflare env object automatically:
| Variable | Purpose |
|----------|---------|
| SENTRY_DSN | DSN for Sentry init |
| SENTRY_RELEASE | Release version string |
| SENTRY_ENVIRONMENT | Environment name (production, staging) |
| SENTRY_TRACES_SAMPLE_RATE | Traces sample rate (parsed as float) |
| SENTRY_DEBUG | Enable debug mode ("true" / "1") |
| SENTRY_TUNNEL | Tunnel URL for event proxying |
| CF_VERSION_METADATA | Cloudflare version metadata binding (auto-detected release) |
These are registered automatically by getDefaultIntegrations():
| Integration | Purpose |
|-------------|---------|
| dedupeIntegration | Prevent duplicate events (disabled for Workflows) |
| inboundFiltersIntegration | Filter events by type, message, URL |
| functionToStringIntegration | Preserve original function names |
| linkedErrorsIntegration | Follow cause chains in errors |
| fetchIntegration | Trace outbound fetch() calls, create breadcrumbs |
| honoIntegration | Deprecated in v10.55.0 — use @sentry/hono package instead. Auto-capture Hono onError exceptions |
| requestDataIntegration | Attach request data to events |
| consoleIntegration | Capture console.* calls as breadcrumbs |
After completing Cloudflare setup, check for companion services:
# Check for companion frontend
ls frontend/ web/ client/ ui/ 2>/dev/null
cat package.json 2>/dev/null | grep -E '"react"|"vue"|"svelte"|"next"|"astro"'
# Check for companion backend in adjacent directories
ls ../backend ../server ../api 2>/dev/null
cat ../go.mod ../requirements.txt ../Gemfile 2>/dev/null | head -3
If a frontend is found, suggest the matching SDK skill:
| Frontend detected | Suggest skill |
|------------------|--------------|
| React | sentry-react-sdk |
| Next.js | sentry-nextjs-sdk |
| Svelte/SvelteKit | sentry-svelte-sdk |
| Vue/Nuxt | See docs.sentry.io/platforms/javascript/guides/vue/ |
If a backend is found in a different directory:
| Backend detected | Suggest skill |
|-----------------|--------------|
| Go (go.mod) | sentry-go-sdk |
| Python (requirements.txt, pyproject.toml) | sentry-python-sdk |
| Ruby (Gemfile) | sentry-ruby-sdk |
| Node.js (Express, Fastify) | sentry-node-sdk |
Connecting frontend and backend with linked Sentry projects enables distributed tracing — stack traces that span your browser, Cloudflare Worker, and backend API in a single trace view.
| Issue | Cause | Solution |
|-------|-------|----------|
| Events not appearing | DSN not set or debug: false hiding errors | Set debug: true temporarily in init options; verify SENTRY_DSN secret is set with wrangler secret list |
| AsyncLocalStorage is not defined | Missing compatibility flag | Add nodejs_als or nodejs_compat to compatibility_flags in wrangler.toml |
| Stack traces show minified code | Source maps not uploaded | Configure @sentry/vite-plugin or run npx @sentry/wizard -i sourcemaps; verify SENTRY_AUTH_TOKEN in CI |
| Events lost on short-lived requests | SDK not flushing before worker terminates | Ensure withSentry or sentryPagesPlugin wraps your handler — they use ctx.waitUntil() to flush |
| Hono errors not captured | Hono app not instrumented | Use @sentry/hono/cloudflare — import sentry middleware and call app.use(sentry(app, options)) |
| Durable Object errors missing | DO class not instrumented | Wrap class with Sentry.instrumentDurableObjectWithSentry() — see references/durable-objects.md |
| D1 queries not creating spans | D1 binding not instrumented | Wrap binding with Sentry.instrumentD1WithSentry(env.DB) before use |
| Scheduled handler not monitored | withSentry not wrapping the handler | Ensure export default Sentry.withSentry(...) wraps your entire exported handler object |
| Release not auto-detected | CF_VERSION_METADATA binding not configured | Add [version_metadata] with binding = "CF_VERSION_METADATA" to wrangler.toml |
| Duplicate events in Workflows | Dedupe integration filtering step failures | SDK automatically disables dedupe for Workflows; verify you use instrumentWorkflowWithSentry |
development
Decide which Sentry signal to reach for when instrumenting code — error, span, span attribute, log, or metric. Use when adding instrumentation and unsure whether something should be a log vs a span vs a metric, when deciding "what to instrument where", when reviewing instrumentation for gaps, or when a coding agent needs a rule for choosing between errors, traces, logs, and metrics. This skill decides WHAT to emit; the sentry-*-sdk skills handle HOW to set each pillar up.
development
Full Sentry SDK setup for React Native and Expo. Use when asked to "add Sentry to React Native", "install @sentry/react-native", "setup Sentry in Expo", or configure error monitoring, tracing, profiling, session replay, or logging for React Native applications. Supports Expo managed, Expo bare, and vanilla React Native.
development
Full Sentry SDK setup for Python. Use when asked to "add Sentry to Python", "install sentry-sdk", "setup Sentry in Python", or configure error monitoring, tracing, profiling, logging, metrics, crons, or AI monitoring for Python applications. Supports Django, Flask, FastAPI, Celery, Starlette, AIOHTTP, Tornado, and more.
development
Configure specific Sentry features beyond basic SDK setup. Use when asked to monitor AI/LLM calls, set up OpenTelemetry pipelines, or create alerts and notifications.