All Skills > SDK Setup > Cloudflare SDK
Sentry 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.
Invoke This Skill When
- User asks to "add Sentry to Cloudflare Workers" or "set up Sentry" in a Cloudflare project
- User wants to install or configure
- User wants error monitoring, tracing, logging, crons, or AI monitoring for Cloudflare Workers or Pages
- User asks about , ,
instrumentDurableObjectWithSentry
, or
- User wants to monitor Durable Objects, Queues, Workflows, Scheduled handlers, or Email handlers on Cloudflare
Note: SDK versions and APIs below reflect current Sentry docs at time of writing (
v10.43.0).
Always verify against
docs.sentry.io/platforms/javascript/guides/cloudflare/ before implementing.
Phase 1: Detect
Run these commands to understand the project before making any recommendations:
bash
# 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: vs |
| Hono framework? | Automatic Hono error handler integration via |
| already installed? | Skip install, go to feature config |
| Durable Objects configured? | Recommend instrumentDurableObjectWithSentry
|
| D1 databases bound? | Recommend |
| Queues configured? | auto-instruments queue handlers |
| Workflows configured? | Recommend instrumentWorkflowWithSentry
|
| Cron triggers configured? | auto-instruments scheduled handlers; recommend Crons monitoring |
| or flag set? | Required — SDK needs |
| AI/LLM libraries? | Recommend AI Monitoring integrations |
| Companion frontend? | Trigger Phase 4 cross-link |
Phase 2: Recommend
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage):
- ✅ Error Monitoring — always; captures unhandled exceptions in fetch, scheduled, queue, email, and Durable Object handlers
- ✅ Tracing — automatic HTTP request spans, outbound fetch tracing, D1 query spans
Optional (enhanced observability):
- ⚡ Logging — structured logs via ; recommend when log search is needed
- ⚡ Crons — detect missed/failed scheduled jobs; recommend when cron triggers are configured
- ⚡ D1 Instrumentation — automatic query spans and breadcrumbs; recommend when D1 is bound
- ⚡ Durable Objects — automatic error capture and spans for DO methods; recommend when DOs are configured
- ⚡ Workflows — automatic span creation for workflow steps; recommend when Workflows are configured
- ⚡ AI Monitoring — Vercel AI SDK, OpenAI, Anthropic, LangChain; recommend when AI libraries detected
Recommendation 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 |
| 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?"
Phase 3: Guide
Option 1: Source Maps Wizard
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 sourcemaps
This 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
wizard only handles source map upload configuration.
Option 2: Manual Setup
Prerequisites: Compatibility Flags
The SDK requires
. Add
one of these flags to your Wrangler config:
wrangler.toml:
toml
compatibility_flags = ["nodejs_als"]
# or: compatibility_flags = ["nodejs_compat"]
wrangler.jsonc:
jsonc
{
"compatibility_flags": ["nodejs_als"]
}
is lighter — it only enables
. Use
if your code also needs other Node.js APIs.
Install
bash
npm install @sentry/cloudflare
Workers Setup
Wrap your handler with
. This automatically instruments
,
,
,
, and
handlers:
typescript
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:
- The first argument is a callback that receives — use this to read secrets like
- The SDK reads DSN, environment, release, debug, tunnel, and traces sample rate from automatically (see Environment Variables)
- wraps all exported handlers — you do not need separate wrappers for , , etc.
Pages Setup
typescript
// 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:
typescript
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 directly (for frameworks like SvelteKit on Cloudflare Pages):
typescript
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),
);
};
Hono on Cloudflare Workers
Hono apps are objects with a
method — wrap them with
directly:
typescript
import { Hono } from "hono";
import * as Sentry from "@sentry/cloudflare";
const app = new Hono();
app.get("/", (ctx) => ctx.json({ message: "Hello" }));
app.get("/error", () => {
throw new Error("Test error");
});
app.onError((err, ctx) => {
return ctx.json({ error: err.message }, 500);
});
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
}),
app,
);
The
(enabled by default) automatically captures errors from Hono's
handler and sets the correct transaction name with the route path.
Set Up the SENTRY_DSN Secret
Store your DSN as a Cloudflare secret — do not hardcode it:
bash
# Local development: add to .dev.vars
echo 'SENTRY_DSN="https://examplePublicKey@o0.ingest.sentry.io/0"' >> .dev.vars
# Production: set as a secret
npx wrangler secret put SENTRY_DSN
Add the binding to your
type:
typescript
interface Env {
SENTRY_DSN: string;
// ... other bindings
}
Source Maps Setup
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
and
scopes.
Step 2: Install the Sentry Vite plugin (most Cloudflare projects use Vite via Wrangler):
bash
npm install @sentry/vite-plugin --save-dev
Step 3: Configure (if your project has one):
typescript
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
bash
SENTRY_AUTH_TOKEN=sntrys_eyJ...
SENTRY_ORG=my-org
SENTRY_PROJECT=my-project
.dev.vars
.env.sentry-build-plugin
Automatic Release Detection
The SDK can automatically detect the release version via Cloudflare's version metadata binding:
wrangler.toml:
toml
[version_metadata]
binding = "CF_VERSION_METADATA"
Release priority (highest to lowest):
- option passed to
- environment variable
- binding
For Each Agreed Feature
Load 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 | | HTTP request tracing, outbound fetch spans, D1 query spans, distributed tracing |
| Logging | | Structured logs via , log-to-trace correlation |
| Crons | | Scheduled handler monitoring, , 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.
Verification
After setup, verify Sentry is working:
typescript
// 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 spans |
| Scheduled monitoring (if configured) | Trigger a cron, check Crons dashboard |
Config Reference
Options
| Option | Type | Default | Notes |
|---|
| | — | Required. Read from automatically if not set |
| | — | 0–1; 1.0 in dev, lower in prod recommended |
| | — | Dynamic sampling function; mutually exclusive with |
| | | Include request headers and cookies in events |
| | | Enable Sentry Logs product |
| | auto | Read from if not set |
| | auto | Detected from or |
| | | Read from if not set. Log SDK activity to console |
| | — | Read from if not set |
| | — | Filter/modify error events before sending |
| | — | Filter/modify transaction events before sending |
| | — | Filter/modify log entries before sending |
| | all URLs | Control which outbound requests get trace headers |
| | | Opt-out of OpenTelemetry compatibility tracer |
instrumentPrototypeMethods
| | | Durable Object: instrument prototype methods for RPC spans |
Environment Variables (Read from )
The SDK reads these from the Cloudflare
object automatically:
| Variable | Purpose |
|---|
| DSN for Sentry init |
| Release version string |
| Environment name (, ) |
SENTRY_TRACES_SAMPLE_RATE
| Traces sample rate (parsed as float) |
| Enable debug mode ( / ) |
| Tunnel URL for event proxying |
| Cloudflare version metadata binding (auto-detected release) |
Default Integrations
These are registered automatically by
:
| Integration | Purpose |
|---|
| Prevent duplicate events (disabled for Workflows) |
inboundFiltersIntegration
| Filter events by type, message, URL |
functionToStringIntegration
| Preserve original function names |
| Follow chains in errors |
| Trace outbound calls, create breadcrumbs |
| Auto-capture Hono exceptions |
| Attach request data to events |
| Capture calls as breadcrumbs |
Phase 4: Cross-Link
After completing Cloudflare setup, check for companion services:
bash
# 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:
If a backend is found in a different directory:
| Backend detected | Suggest skill |
|---|
| Go () | |
| Python (, ) | |
| Ruby () | |
| Node.js (Express, Fastify) | |
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.
Troubleshooting
| Issue | Cause | Solution |
|---|
| Events not appearing | DSN not set or hiding errors | Set temporarily in init options; verify secret is set with |
AsyncLocalStorage is not defined
| Missing compatibility flag | Add or to in |
| Stack traces show minified code | Source maps not uploaded | Configure or run npx @sentry/wizard -i sourcemaps
; verify in CI |
| Events lost on short-lived requests | SDK not flushing before worker terminates | Ensure or wraps your handler — they use to flush |
| Hono errors not captured | Hono app not wrapped with | Pass the Hono app as the second argument to |
| 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 | not wrapping the handler | Ensure export default Sentry.withSentry(...)
wraps your entire exported handler object |
| Release not auto-detected | binding not configured | Add with binding = "CF_VERSION_METADATA"
to |
| Duplicate events in Workflows | Dedupe integration filtering step failures | SDK automatically disables dedupe for Workflows; verify you use instrumentWorkflowWithSentry
|