getsentry / getsentry/sentry-javascript

`instrumentLangGraph` and `createLangChainCallbackHandler` silently drop spans when used together

オープン
#19,627 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
Browser Bug
主要言語
TypeScript
スター
8.7k
フォーク
1.8k
平均マージ
1日 17時間
マージ済み PR(30日)
515

説明

### Is there an existing issue for this?

- [x] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- [x] I have reviewed the documentation https://docs.sentry.io/
- [x] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

### How do you use Sentry?

Sentry Saas (sentry.io)

### Which SDK are you using?

@sentry/browser

### SDK Version

^10.40.0

### Framework Version

_No response_

### Link to Sentry event

https://pri-dogfooding-ai.sentry.io/insights/ai-agents/?project=4510951776059472&statsPeriod=30d&trace=043dd6239e7645d9b70f641fe3ec2f83&span=undefined&trace-timestamp=1772622191

### Reproduction Example/SDK Setup

_No response_

### Steps to Reproduce

```js
const graph = new StateGraph(IdeaState)
.addNode("expand", expandNode) // calls llm.invoke()
.addNode("validate", validateNode) // calls llm.invoke()
.addNode("differentiate", diffNode) // calls llm.invoke()
.addNode("roadmap", roadmapNode) // calls llm.invoke()
.addNode("pitch", pitchNode) // calls llm.invoke()
.addEdge(START, "expand")
.addEdge("expand", "validate")
.addEdge("validate", "differentiate")
.addEdge("differentiate", "roadmap")
.addEdge("roadmap", "pitch")
.addEdge("pitch", END);

Sentry.instrumentLangGraph(graph, { recordInputs: true, recordOutputs: true });
const compiled = graph.compile({ name: "idea-forge" });

const sentryHandler = Sentry.createLangChainCallbackHandler({
recordInputs: true,
recordOutputs: true,
});
const result = await compiled.invoke({ idea: "test" }, { callbacks: [sentryHandler] });
```

### Expected Result

All 5 LLM calls should produce `chat` spans in the trace.

### Actual Result

| Setup | `chat` spans captured |
|-------|----------------------|
| `instrumentLangGraph` + `createLangChainCallbackHandler` | **1 out of 5** |
| `createLangChainCallbackHandler` only | 5 out of 5 |
| `instrumentLangGraph` only | 0 (expected — no callback handler) |

4 out of 5 `chat` spans are silently dropped with no error or warning.

Additionally, the trace contains multiple spurious nested `invoke_agent` sub-spans with near-zero durations (0.20ms) that should not exist:

```
invoke_agent idea-forge 7.43s ← top-level (expected)
invoke_agent idea-forge 2.70ms ← spurious
invoke_agent idea-forge 1.60ms ← spurious
invoke_agent idea-forge 0.20ms ← spurious
invoke_agent idea-forge 4.41s
chat claude-haiku-4-5-20251001 4.41s ← only 1 of 5 chat spans
invoke_agent idea-forge 0.20ms ← spurious
invoke_agent idea-forge 0.20ms ← spurious
```

### Additional Context

**Possible Root Cause:**

`instrumentLangGraph` wraps `invoke()` inside `Sentry.startSpan()`. As async execution passes through sequential nodes, the span context from `startSpan` is not consistently maintained across all node invocations. Some `handleChatModelStart` callbacks from the handler fire outside an active span context and their spans are dropped.

### Priority

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。