Cloudflare Quick Start for Flue

Learn how to send Flue agent traces, model calls, tool executions, and errors to Sentry from Cloudflare Workers.

Flue 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.

Running Flue on Node.js? Follow the Flue Quick Start instead.

Before you begin, you need:

  • A Sentry account and project. 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.

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

Install the Sentry Cloudflare SDK:

Copied
npm install @sentry/cloudflare@^11.0.0

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

vite.config.mts
Copied
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:

src/sentry.ts
Copied
import { extend } from "@flue/runtime/cloudflare";
import * as Sentry from "@sentry/cloudflare";

export const cloudflare = extend({
  wrap: (Final) =>
    Sentry.instrumentDurableObjectWithSentry(
      (env: Env) => ({
        dsn: "___PUBLIC_DSN___",
        // ___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:

src/agents/support.ts
Copied
export { cloudflare } from "../sentry.ts";

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

wrangler.jsonc
Copied
{
  "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 below.

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:

src/sentry.ts
Copied
Sentry.instrumentDurableObjectWithSentry(
  (env: Env) => ({
    dsn: "___PUBLIC_DSN___",
    dataCollection: {
      genAI: { inputs: false, outputs: false },
    },
  }),
  Final,
);

See dataCollection documentation for details on privacy control options.

Sentry groups a multi-turn chat into a single Conversation 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'.

Send a message to one of your agents, then open Explore → Agents in Sentry. Select the conversation to open its detail. The timeline shows the agent turn, model calls, tool executions, token usage, latency, and 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.

  • 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.

What gets captured?

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

Flue OperationSentry Operation
Agent submissiongen_ai.invoke_agent
Model turngen_ai.chat
Tool executiongen_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.

  • @sentry/cloudflare: >=11.0.0
  • @flue/runtime: >=2.0.0 <3.0.0
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").