---
title: "LangGraph"
description: "Adds instrumentation for the LangGraph SDK. (default)"
url: https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph/
---

# LangGraph for Cloudflare

Requires SDK version `11.0.0` or higher. On earlier versions, see the [Agent Tracing](https://docs.sentry.io/platforms/javascript/agent-tracing.md) setup for your SDK.

*Import name: `Sentry.langGraphIntegration`*

This integration is enabled by default when tracing is enabled. If you'd like to modify your default integrations, read [this](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations.md#modifying-default-integrations).

The `langGraphIntegration` adds instrumentation for [`@langchain/langgraph`](https://www.npmjs.com/package/@langchain/langgraph) to capture [agent tracing](https://docs.sentry.io/platforms/javascript/guides/cloudflare/agent-tracing.md) `gen_ai` spans, recording model, token usage, latency, and (when enabled) inputs and outputs.

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  // Tracing must be enabled for agent tracing to work
  tracesSampleRate: 1.0,
  integrations: [Sentry.langGraphIntegration()],
});
```

## [Supported Operations](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph.md#supported-operations)

By default, tracing support is added to the following LangGraph operations:

* **Agent Creation** (`gen_ai.create_agent`) - Captures spans when compiling a StateGraph into an executable agent
* **Agent Invocation** (`gen_ai.invoke_agent`) - Captures spans for agent execution via `invoke()`
* **Classifier Evaluations** (`gen_ai.evaluate`) - Captures spans for `TypeSafeClassifier` calls in graph nodes

## [Trace Classifier Evaluations](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph.md#trace-classifier-evaluations)

Available since: `v11.6.0`

When a graph node calls a `TypeSafeClassifier` from [`@langchain/typesafe`](https://www.npmjs.com/package/@langchain/typesafe), the [LangChain integration](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langchain.md#trace-classifier-evaluations) records the call as a `gen_ai.evaluate` span. The span is a child of the graph's `invoke_agent` span and records the graph name as the agent name. No additional setup is needed.

```javascript
import { Annotation, END, START, StateGraph } from "@langchain/langgraph";
import { TypeSafeClassifier } from "@langchain/typesafe";

const classifier = new TypeSafeClassifier({
  questions: {
    urgent: { type: "noul", instructions: "Is this urgent?" },
  },
});

const State = Annotation.Root({
  ticket: Annotation(),
  urgent: Annotation(),
});

const graph = new StateGraph(State)
  .addNode("triage", async (state) => {
    const result = await classifier.invoke(state.ticket);
    return { urgent: result.nouls.urgent.noul };
  })
  .addEdge(START, "triage")
  .addEdge("triage", END)
  .compile({ name: "triage_graph" });

await graph.invoke({ ticket: "My payouts have been failing for 3 days." });
```

The evaluation state, questions, and answers follow the LangChain integration's `recordInputs` and `recordOutputs` options.

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

* `@langchain/langgraph`: `>=0.2.0 <2.0.0`

## [Options](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph.md#options)

### [`recordInputs`](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph.md#recordinputs)

*Type: `boolean` (optional)*

Records inputs to LangGraph operations (such as messages and state data passed to the graph).

Defaults to `true` if `dataCollection.genAI.inputs` is `true`, which is the default.

### [`recordOutputs`](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph.md#recordoutputs)

*Type: `boolean` (optional)*

Records outputs from LangGraph operations (such as generated responses, agent outputs, and final state).

Defaults to `true` if `dataCollection.genAI.outputs` is `true`, which is the default.

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  tracesSampleRate: 1.0,
  integrations: [
    Sentry.langGraphIntegration({
      recordInputs: false,
      recordOutputs: false,
    }),
  ],
});
```

## [Manual Instrumentation](https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/integrations/langgraph.md#manual-instrumentation)

*Import names: `Sentry.instrumentStateGraph`, `Sentry.instrumentCreateReactAgent`*

If your application does not use automatic instrumentation, wrap your agent after setting up Sentry. Two helpers are available, depending on how you build your agent:

* **`instrumentStateGraph`**: for graphs you build yourself with `StateGraph`. Call it on the graph **before** calling `.compile()`.
* **`instrumentCreateReactAgent`**: for LangGraph's prebuilt `createReactAgent`. Wrap the factory, then use the wrapped version exactly like `createReactAgent`. This also captures the model and wraps tools, so you get `execute_tool` spans as well.

Both accept the same `recordInputs` and `recordOutputs` options as the integration.

Instrumenting a `StateGraph`:

```javascript
import { ChatOpenAI } from "@langchain/openai";
import {
  StateGraph,
  MessagesAnnotation,
  START,
  END,
} from "@langchain/langgraph";
import { SystemMessage, HumanMessage } from "@langchain/core/messages";

// Create LLM call
const llm = new ChatOpenAI({
  modelName: "gpt-4o",
  apiKey: "your-api-key",
});

async function callLLM(state) {
  const response = await llm.invoke(state.messages);

  return {
    messages: [...state.messages, response],
  };
}

// Create the agent
const agent = new StateGraph(MessagesAnnotation)
  .addNode("agent", callLLM)
  .addEdge(START, "agent")
  .addEdge("agent", END);

// Instrument the graph before compiling
Sentry.instrumentStateGraph(agent, {
  recordInputs: false,
  recordOutputs: false,
});

const graph = agent.compile({ name: "my_agent" });

// Invoke the agent
const result = await graph.invoke({
  messages: [
    new SystemMessage("You are a helpful assistant."),
    new HumanMessage("Hello!"),
  ],
});
```

Instrumenting a prebuilt `createReactAgent`:

```javascript
import { createReactAgent } from "@langchain/langgraph/prebuilt";

// Instrument createReactAgent, then use the wrapped version in its place
const instrumentedCreateReactAgent =
  Sentry.instrumentCreateReactAgent(createReactAgent);

const agent = instrumentedCreateReactAgent({ llm, tools });
```
