Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/platforms/javascript/common/agent-tracing/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export default Sentry.withSentry(
);
```

On the default CF entrypoint, control Vercel AI I/O with `experimental_telemetry` per call (or integration-level `record*` via `nodejs_compat`). See each integration page.
On Cloudflare, control Vercel AI I/O with integration-level `record*` options or with `experimental_telemetry` per call. See each integration page.

</PlatformSection>

Expand Down
35 changes: 12 additions & 23 deletions docs/platforms/javascript/common/agent-tracing/vercelai.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,9 @@ Everything else depends on which runtime you're in:

<PlatformSection supported={['javascript.cloudflare']}>

Cloudflare Workers can't load OpenTelemetry instrumentation. On both entrypoints, Sentry reads the spans the AI SDK emits on its own instead of patching your call sites, so you must pass `experimental_telemetry` on every call. The <PlatformLink to="/features/nodejs-compat">`@sentry/cloudflare/nodejs_compat`</PlatformLink> entrypoint adds the Node.js APIs the AI SDK v7 telemetry channel needs.
Cloudflare Workers can't load OpenTelemetry instrumentation. Sentry reads the spans the AI SDK emits on its own instead of patching your call sites, so you must pass `experimental_telemetry` on every call.

Your entrypoint decides the rest:

| | `@sentry/cloudflare` | `@sentry/cloudflare/nodejs_compat` |
| ---------------------------- | -------------------- | ---------------------------------- |
| Record inputs and outputs | Per call only | Integration or per call |
| AI SDK v7 | Not supported | Supported |
| Minimum Sentry SDK | `10.6.0` | `10.64.0` |
| Minimum `compatibility_date` | `2024-09-23` | `2026-02-19` |
The AI SDK v7 telemetry channel needs Node.js APIs, which the Worker gets from the `nodejs_compat` compatibility flag. Set a `compatibility_date` of `2026-02-19` or later to record AI SDK v7 spans.

</PlatformSection>

Expand Down Expand Up @@ -146,10 +139,10 @@ Deno can't load OpenTelemetry instrumentation, so Sentry can't patch your call s

### AI SDK v7

Use the <PlatformLink to="/features/nodejs-compat">`@sentry/cloudflare/nodejs_compat`</PlatformLink> entrypoint and enable the Wrangler `nodejs_compat` flag:
Enable the Wrangler `nodejs_compat` flag and set a `compatibility_date` of `2026-02-19` or later:

```javascript
import * as Sentry from "@sentry/cloudflare/nodejs_compat";
import * as Sentry from "@sentry/cloudflare";

export default Sentry.withSentry(
(env) => ({
Expand Down Expand Up @@ -199,7 +192,7 @@ export default Sentry.withSentry(
);
```

On both entrypoints, adding the integration is not enough on its own. Cloudflare can't patch your call sites, so you must also pass `experimental_telemetry` on every call — including on `nodejs_compat`. See [Turn on telemetry](#turn-on-telemetry).
Adding the integration is not enough on its own. Cloudflare can't patch your call sites, so you must also pass `experimental_telemetry` on every call. See [Turn on telemetry](#turn-on-telemetry).

</PlatformSection>

Expand Down Expand Up @@ -286,12 +279,12 @@ const result = await generateText({

<PlatformSection supported={['javascript.cloudflare']}>

### `@sentry/cloudflare/nodejs_compat`
### On the integration

Set the options on the integration to cover every call:

```javascript
import * as Sentry from "@sentry/cloudflare/nodejs_compat";
import * as Sentry from "@sentry/cloudflare";

export default Sentry.withSentry(
(env) => ({
Expand All @@ -312,13 +305,9 @@ export default Sentry.withSentry(
);
```

### `@sentry/cloudflare`

<Alert level="warning">

The default entrypoint ignores `recordInputs` and `recordOutputs` on the integration. It accepts no error and logs no warning — your prompts are simply missing. Set both per call.
### Per call

</Alert>
Or set them on a single call, which overrides the integration for that call:

```javascript
const result = await generateText({
Expand Down Expand Up @@ -470,7 +459,7 @@ Pass these to `Sentry.vercelAIIntegration()`. The Edge runtime accepts `enableTr

<PlatformSection supported={['javascript.cloudflare']}>

Pass these to `Sentry.vercelAIIntegration()`. The default `@sentry/cloudflare` entrypoint accepts `enableTruncation` only; <PlatformLink to="/features/nodejs-compat">`nodejs_compat`</PlatformLink> also accepts `recordInputs` and `recordOutputs`. Neither has module detection to override, so `force` does not apply.
Pass these to `Sentry.vercelAIIntegration()`. Cloudflare accepts `enableTruncation`, `recordInputs` and `recordOutputs`. It has no module detection to override, so `force` does not apply.

</PlatformSection>

Expand Down Expand Up @@ -603,8 +592,8 @@ Plus `generate()` and `stream()` on [`ToolLoopAgent`](#toolloopagent).

<PlatformSection supported={['javascript.cloudflare']}>

- Sentry SDK: `10.6.0`+ with `@sentry/cloudflare`
- Sentry SDK: `10.64.0`+ with `@sentry/cloudflare/nodejs_compat`, required for `ai` v7
- Sentry SDK: `10.6.0`+
- `compatibility_date`: `2026-02-19`+, required for `ai` v7

</PlatformSection>

Expand Down
30 changes: 5 additions & 25 deletions docs/platforms/javascript/common/mcp-monitoring/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,11 @@ These options override the corresponding `dataCollection.genAI.inputs` and `data

## Preserve MCP Spans After the Response

Cloudflare MCP work can finish after the Worker returns an HTTP response, including work kept alive with `waitUntil()`. With the static trace lifecycle, Sentry snapshots the request transaction when the response is returned, so MCP spans that finish later may be missing.
Cloudflare MCP work can finish after the Worker returns an HTTP response, including work kept alive with `waitUntil()`. The SDK streams spans by default, sending each sampled span as it finishes, so this work is captured without extra configuration. You still need to wrap the MCP server as shown above.

Set `traceLifecycle: "stream"` so the SDK can send each sampled span when it finishes. This changes how spans are delivered; you still need to wrap the MCP server as shown above. Span streaming on Cloudflare requires `@sentry/cloudflare` version `10.49.0` or newer.
If you set `traceLifecycle: "static"`, the SDK snapshots the request transaction when the response is returned and MCP spans that finish later are dropped. Remove the option to get them back.

```javascript {filename:index.js}
import * as Sentry from "@sentry/cloudflare";

const worker = {
async fetch(request, env, ctx) {
return handleMcpRequest(request, env, ctx);
},
};

export default Sentry.withSentry(
(env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
traceLifecycle: "stream",
}),
worker
);
```

Stream mode sends span records instead of assembling one transaction event with embedded spans. `beforeSendTransaction` and `ignoreTransactions` don't apply to streamed spans. See <PlatformLink to="/tracing/streamed-spans/">Streamed Spans</PlatformLink> for the `beforeSendSpan` and `ignoreSpans` configuration.
Streaming sends span records instead of assembling one transaction event with embedded spans. `beforeSendTransaction` and `ignoreTransactions` don't apply to streamed spans. See <PlatformLink to="/tracing/streamed-spans/">Streamed Spans</PlatformLink> for the `beforeSendSpan` and `ignoreSpans` configuration.

If you use `McpAgent`, wrap the `McpServer` returned by its `server` getter, and wrap the Agent class separately with `instrumentAgentWithSentry` to preserve request and RPC context. Agent instrumentation, MCP server wrapping, and span streaming solve different parts of the setup; none replaces the others. See <PlatformLink to="/agent-tracing/agents-sdk/">Agents SDK</PlatformLink>.

Expand All @@ -90,7 +71,7 @@ If you use `McpAgent`, wrap the `McpServer` returned by its `server` getter, and

## Hono on Cloudflare Workers

If your Hono app runs on Cloudflare Workers, MCP work can finish after the Worker returns its response. Set `traceLifecycle: "stream"` in the Hono Sentry middleware so each sampled span is sent when it finishes:
If your Hono app runs on Cloudflare Workers, MCP work can finish after the Worker returns its response. The middleware streams spans by default, sending each sampled span as it finishes, so that work is captured on its own:

```javascript {filename:index.js}
import { sentry } from "@sentry/hono/cloudflare";
Expand All @@ -99,12 +80,11 @@ app.use(
sentry(app, {
dsn: "___PUBLIC_DSN___",
tracesSampleRate: 1.0,
traceLifecycle: "stream",
})
);
```

This changes how spans are delivered; it doesn't replace `wrapMcpServerWithSentry`. Stream mode requires `@sentry/hono` and `@sentry/cloudflare` version `10.49.0` or newer. See <PlatformLink to="/tracing/streamed-spans/">Streamed Spans</PlatformLink> for configuration and filtering differences.
Setting `traceLifecycle: "static"` drops the spans that finish after the response. Streaming changes how spans are delivered; it doesn't replace `wrapMcpServerWithSentry`. See <PlatformLink to="/tracing/streamed-spans/">Streamed Spans</PlatformLink> for configuration and filtering differences.

</PlatformSection>

Expand Down
85 changes: 85 additions & 0 deletions docs/platforms/javascript/common/troubleshooting/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -691,4 +691,89 @@ shamefully-hoist=true
</Expandable>
</PlatformSection>

<PlatformSection supported={['javascript.cloudflare']}>
<Expandable permalink title="Spans from waitUntil() or other work after the response are missing">
Cloudflare's [`waitUntil()`](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#contextwaituntil) lets work continue after the Worker returns a response. Whether those spans arrive depends on your trace lifecycle.

On the static lifecycle, the SDK snapshots the request transaction when the response is returned, so anything finishing later is dropped. Streaming sends each sampled span as it finishes instead, which captures deferred work.

From version `11.0.0`, the SDK streams by default, so this is only a problem if something set the static lifecycle explicitly. Remove it:

```javascript {filename:index.js}
export default Sentry.withSentry(
(env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
// Remove this to stream spans as they finish
// traceLifecycle: "static",
}),
worker
);
```

On version `10.x` the static lifecycle is the default, so missing deferred spans are expected until you opt in. Set `traceLifecycle: "stream"`, which needs `@sentry/cloudflare` version `10.49.0` or newer:

```javascript {filename:index.js}
export default Sentry.withSentry(
(env) => ({
dsn: env.SENTRY_DSN,
tracesSampleRate: 1.0,
traceLifecycle: "stream",
}),
worker
);
```

If you need the static lifecycle for another reason, wrap the background work in its own span with `forceTransaction: true`, which records it as a separate transaction. `forceTransaction` has no effect while streaming.

```javascript {filename:index.js}
ctx.waitUntil(
Sentry.startSpan(
{ name: "background.task", op: "task", forceTransaction: true },
() => updateCacheAndDatabase()
)
);
```

See <PlatformLink to="/tracing/streamed-spans/">Streamed Spans</PlatformLink> for how streaming changes filtering with `beforeSendSpan` and `ignoreSpans`.

</Expandable>

<Expandable permalink title="My events have no release, or the wrong one">
The SDK resolves the release from the `release` option you pass, then the `SENTRY_RELEASE` environment variable, then the `CF_VERSION_METADATA.id` binding. The first one that is set wins. Reading the binding automatically needs `@sentry/cloudflare` version `10.35.0` or newer; on earlier versions, pass it as the `release` option yourself, as shown at the end of this entry.

If your events carry no release, check that the binding is declared in your wrangler config:

```jsonc {tabTitle:JSON} {filename:wrangler.jsonc}
{
"version_metadata": {
"binding": "CF_VERSION_METADATA"
}
}
```

```toml {tabTitle:Toml} {filename:wrangler.toml}
[version_metadata]
binding = "CF_VERSION_METADATA"
```

The binding only carries a meaningful version ID on a deployed Worker. In local development the value is [not applicable or accurate](https://developers.cloudflare.com/workers/local-development/), so events from `wrangler dev` or `vite dev` won't match a release in Sentry.

If your events carry a release you didn't expect, something further up the list is set. A `SENTRY_RELEASE` variable left over in your Worker's environment overrides the binding, and an explicit `release` option overrides both.

To pin the release to the Cloudflare version ID no matter what else is set, pass it yourself:

```javascript
Sentry.withSentry(
(env) => ({
dsn: "___PUBLIC_DSN___",
release: env.CF_VERSION_METADATA?.id,
})
// ...
);
```

</Expandable>
</PlatformSection>

If you need additional help, you can [ask on GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose). Customers on a paid plan may also contact support.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const MyAgent = Sentry.instrumentAgentWithSentry(

The Worker that calls the agent names its binding in `rpcTracePropagationBindings`. See <PlatformLink to="/tracing/distributed-tracing/#rpc-trace-propagation">RPC Trace Propagation</PlatformLink>.

`instrumentAgentWithSentry` works with `Agent` from `agents`, `AIChatAgent` from `@cloudflare/ai-chat`, and `McpAgent` from `agents/mcp`. When you build with the <PlatformLink to="/features/vite-plugin/">Sentry Cloudflare Vite plugin</PlatformLink>'s `autoInstrumentation`, the plugin detects and wraps Agent classes automatically.
`instrumentAgentWithSentry` works with `Agent` from `agents`, `AIChatAgent` from `@cloudflare/ai-chat`, and `McpAgent` from `agents/mcp`. When you build with the <PlatformLink to="/install/vite-plugin/">Sentry Cloudflare Vite plugin</PlatformLink>, it detects and wraps Agent classes for you, so you only need this wrapper on a plain Wrangler build.

## Conversation IDs

Expand Down Expand Up @@ -93,7 +93,7 @@ Populate the Conversations **User** column with `Sentry.setUser` on every reques

- <PlatformLink to="/agent-tracing/workers-ai/">Workers AI</PlatformLink>
- <PlatformLink to="/features/durableobject/">Durable Objects</PlatformLink>
- <PlatformLink to="/features/vite-plugin/">Vite Plugin</PlatformLink>
- <PlatformLink to="/install/vite-plugin/">Vite Plugin</PlatformLink>
- <PlatformLink to="/agent-tracing/#tracking-conversations">
Tracking Conversations
</PlatformLink>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
---
title: Prisma
description: "Adds instrumentation for Prisma ORM queries on Cloudflare Workers running with Node.js compatibility."
description: "Adds instrumentation for Prisma ORM queries on Cloudflare Workers."
---

<Alert>

On Cloudflare, the `prismaIntegration` is only available through the <PlatformLink to="/features/nodejs-compat">`@sentry/cloudflare/nodejs_compat`</PlatformLink> entrypoint, which requires SDK version `10.64.0` or higher.

</Alert>

_Import name: `Sentry.prismaIntegration`_

Sentry supports tracing [Prisma ORM](https://www.prisma.io/) queries with the Prisma integration. The integration creates a span for each query and reports relevant details to Sentry.

To enable it on Cloudflare, import Sentry from the `@sentry/cloudflare/nodejs_compat` entrypoint and add the `prismaIntegration` to your `Sentry.init` call:
The integration relies on Node.js APIs, so your Worker must run with the `nodejs_compat` compatibility flag. Add the `prismaIntegration` to your `Sentry.init` call:

```javascript {3,5}
import * as Sentry from "@sentry/cloudflare/nodejs_compat";
import * as Sentry from "@sentry/cloudflare";

Sentry.init({
tracesSampleRate: 1.0,
Expand Down

This file was deleted.

Loading
Loading