fix(server-utils): Don't capture caller-handled LangGraph errors - #23594
fix(server-utils): Don't capture caller-handled LangGraph errors#23594nicohrubec wants to merge 1 commit into
Conversation
LangGraph's compiled-graph invoke and tool-node wrappers called captureException with handled: false and then rethrew. The error rejects invoke() to the caller, so the instrumentation recorded an "unhandled crash" for an error the application handles, the same issue fixed for the client wrappers (#23024) and LangChain. The span is still marked failed and the error still propagates; only the event goes away. The integration tests masked these with .ignore('event'); those masks are removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1d2b83c. Configure here.
| createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => { | ||
| test('should instrument LangGraph with default PII settings', async () => { | ||
| await createRunner() | ||
| .ignore('event') |
There was a problem hiding this comment.
Fix lacks error-path regression test
Low Severity
This fix PR does not add a test that covers the regression. The integration tests only drop .ignore('event') on success-path scenarios, so they would still pass if captureException were restored. A fix PR needs a unit, integration, or E2E test that fails without the change and passes with it: invoke that throws, the caller catching it, and no error event being sent. The related LangChain tests already follow that pattern with an error-model invoke inside try/catch.
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 1d2b83c. Configure here.
size-limit report 📦
|


Note
Stacked on top of #23593 (LangChain). Review/merge that one first; this PR targets its branch so the diff stays scoped to LangGraph.
LangGraph's compiled-graph invoke wrapper and tool-node wrapper called
captureException(error, { handled: false })and then rethrew. The error rejectsinvoke()to the caller, so the instrumentation recorded an "unhandled crash" for an error the application handles. This is the same problem fixed for the OpenAI, Anthropic, and Google GenAI client wrappers in #23024, and for LangChain in #23593.The span is still marked
internal_errorand the error still propagates to the caller, so only the event goes away, leaving thehandleddecision to the application boundary.The integration tests masked these captures with
.ignore('event'); those masks are removed.Related to #23023