---
title: "Cloudflare Quick Start"
description: "Learn how to send Flue agent traces, model calls, tool executions, and errors to Sentry from Cloudflare Workers."
url: https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare/
---

# Cloudflare Quick Start | Sentry for Flue

[Flue](https://flueframework.com/) is an open TypeScript framework for building AI agents, made by the Astro team. This guide sets up the Sentry SDK in a Flue app running on Cloudflare Workers so agent turns, model calls, tool executions, and errors flow into [Sentry Agent Tracing](https://docs.sentry.io/product/agents.md).

This guide covers the Sentry SDK-based setup, which replaces the `flue add tooling sentry` blueprint. If you previously ran the blueprint, remove its `createOpenTelemetryInstrumentation` call — otherwise, you will get duplicate spans.

Running Flue on Node.js? Follow the [Flue Quick Start](https://docs.sentry.io/platforms/javascript/guides/flue.md) instead.

## [Prerequisites](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#prerequisites)

Before you begin, you need:

* A Sentry [account](https://sentry.io/signup/) and [project](https://docs.sentry.io/product/projects.md). The project's DSN tells the SDK where to send data.
* A Flue application using `@flue/runtime` version `2.0.0` or later, targeting Cloudflare.
* `@sentry/cloudflare` version `11.0.0` or later.

## [Install](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#install)

Choose the features you want to configure, and this guide will show you how:

Error Monitoring\[ ]Tracing

Install the Sentry Cloudflare SDK:

```bash
npm install @sentry/cloudflare@^11.0.0
```

*Other available variations of the above snippet: yarn, pnpm*

## [Configure](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#configure)

Add the Sentry Vite plugin to your Vite config, after Flue's:

```typescript
import { cloudflare } from "@cloudflare/vite-plugin";
import { flue, flueWorkerConfig } from "@flue/vite";
import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [
    flue(),
    cloudflare({ config: flueWorkerConfig() }),
    sentryCloudflareVitePlugin(),
  ],
});
```

The plugin registers the Flue instrumentation for you at build time, so you don't write an `instrument()` call as you do on Node.js. It instruments the other libraries your tools call at the same point, so their spans land in the agent's trace.

Each Flue agent runs in its own Durable Object, which is a separate isolate from your Worker entry. `Sentry.init()` has to run inside it, so create a module that wraps the generated agent Durable Object:

```typescript
import { extend } from "@flue/runtime/cloudflare";
import * as Sentry from "@sentry/cloudflare";

export const cloudflare = extend({
  wrap: (Final) =>
    Sentry.instrumentDurableObjectWithSentry(
      (env: Env) => ({
        dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
        // ___PRODUCT_OPTION_START___ performance

        // Set tracesSampleRate to 1.0 to capture 100%
        // of spans for tracing.
        // We recommend adjusting this value in production.
        tracesSampleRate: 1.0,
        // ___PRODUCT_OPTION_END___ performance
      }),
      Final,
    ),
});
```

Re-export it as `cloudflare` from each agent module. This is how Flue applies the wrapper — defining it anywhere else has no effect:

```typescript
export { cloudflare } from "../sentry.ts";
```

Without this re-export the agent still runs normally and nothing errors, but no `Sentry.init()` ever runs in that isolate, so nothing is captured at all.

Enable Node.js compatibility in your Wrangler config so the SDK can run on Workers:

```json
{
  "compatibility_flags": ["nodejs_compat"]
}
```

With this setup, Sentry captures errors thrown by your agents and tools, and AI spans for every run (agent turns, model calls, tool executions, token usage, and latency). Manual spans you start inside a tool nest under that tool's span.

To review what's captured and turn recording of prompts and responses off, see [Privacy Controls](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#privacy-controls) below.

### [Privacy Controls](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#privacy-controls)

The SDK will record generative AI inputs and outputs (the prompts your agent sends and the model responses it receives) by default. To turn recording off, set `genAI.inputs` and `genAI.outputs` to `false` in `dataCollection`:

```typescript
Sentry.instrumentDurableObjectWithSentry(
  (env: Env) => ({
    dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
    dataCollection: {
      genAI: { inputs: false, outputs: false },
    },
  }),
  Final,
);
```

See [`dataCollection` documentation](https://docs.sentry.io/platforms/javascript/guides/flue/configuration/options.md#dataCollection) for details on privacy control options.

### [Link Conversations](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#link-conversations)

Sentry groups a multi-turn chat into a single [Conversation](https://docs.sentry.io/product/agents/conversations.md) automatically — there's no Sentry-specific setup. Flue already tracks a conversation id per conversation, and the SDK maps it to `gen_ai.conversation.id` on the agent, model, and tool spans of every turn.

The agent span also carries `gen_ai.agent.name`, so you can tell a lead agent's runs from its subagents'.

## [Verify](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#verify)

Send a message to one of your agents, then open [Agent Tracing](https://docs.sentry.io/product/agents.md) in Sentry and select the run. The timeline shows the agent turn, the model calls, the tool executions, token usage, and latency, plus any errors your tools threw.

If no data appears, confirm that:

* The `dsn` belongs to the Sentry project you're viewing.
* `tracesSampleRate` is greater than `0`.
* Your agent completed at least one turn after you added the setup.

## [Troubleshooting](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#troubleshooting)

* **The agent runs but nothing reaches Sentry.** Confirm each agent module re-exports `cloudflare` from your `src/sentry.ts`. This is the most common cause, and it fails silently.
* **`instrument.server.ts` has no effect.** That convention needs a worker entry named in Wrangler's `main`. Flue supplies its own virtual entry instead, so the file is never picked up. Use the Durable Object wrapper above.
* **Token and cost values are doubled.** Remove the `createOpenTelemetryInstrumentation` call left over from the `flue add tooling sentry` blueprint.

## [Next Steps](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#next-steps)

* [Name your agents](https://docs.sentry.io/product/agents/naming.md) so you can identify them in the Agents Dashboard.
* [Track AI agent spend with dashboards and alerts](https://sentry.io/cookbook/monitor-ai-agent-spend-with-dashboards-and-alerts/): build a dashboard for cost, tokens, models, and conversations.
* [Flue's observability guide](https://flueframework.com/docs/guide/observability/): the event model behind the spans, from the Flue side.
* Use the appropriate [JavaScript framework guide](https://docs.sentry.io/platforms/javascript.md) for application monitoring in a separate frontend or service.

What gets captured?

Sentry's Flue integration maps Flue's runtime operations to Sentry operations for the Agents dashboards:

| Flue Operation   | Sentry Operation      |
| ---------------- | --------------------- |
| Agent submission | `gen_ai.invoke_agent` |
| Model turn       | `gen_ai.chat`         |
| Tool execution   | `gen_ai.execute_tool` |

Spans are tagged with `sentry.origin: auto.ai.flue` and carry the model, token usage, and finish reasons for the turn.

A `chat` span also carries `flue.turn.purpose`, which is how you tell a context-compaction turn from a user-facing one. There's no conventional attribute for that distinction.

A tool that throws is captured as an error and its span is marked failed. Flue catches the throw and hands it back to the model as a tool result, so the error is reported as handled.

## [Supported Versions](https://docs.sentry.io/platforms/javascript/guides/flue/cloudflare.md#supported-versions)

* `@sentry/cloudflare`: `>=11.0.0`
* `@flue/runtime`: `>=2.0.0 <3.0.0`
