Skip to content

fix: catch tool errors in wrapToolCall middleware to prevent crash#437

Open
Himanshu Kumar (himanshu231204) wants to merge 2 commits into
langchain-ai:mainfrom
himanshu231204:fix/tool-error-unhandled-rejection
Open

fix: catch tool errors in wrapToolCall middleware to prevent crash#437
Himanshu Kumar (himanshu231204) wants to merge 2 commits into
langchain-ai:mainfrom
himanshu231204:fix/tool-error-unhandled-rejection

Conversation

@himanshu231204

@himanshu231204 Himanshu Kumar (himanshu231204) commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Related Issue

Closes #426


Problem

Any tool error during agent execution crashes the entire run via unhandled promise rejection in the langchain tool-call transformer.

Root Cause

When wrapToolCall middleware is present, tool errors get wrapped in MiddlewareError by the composition layer. ToolNode.#handleError then re-throws them as fatal because handleToolErrors !== true. The createToolCallTransformer rejects output promises that nobody catches, leading to UnhandledPromiseRejection and a process crash.

Crash Path

Tool throws error
  → wrapToolCall composition wraps in MiddlewareError
  → ToolNode.#handleError: errorFromMiddleware=true, handleToolErrors!==true
  → re-throws as fatal error
  → Agent run fails
  → createToolCallTransformer.fail() rejects output promises
  → No .catch() on promises
  → UnhandledPromiseRejection → CRASH

Changes

src/agent/okf-middleware.ts

  1. Restructured wrapToolCall — Catch tool execution errors inside the middleware and convert them to ToolMessages before they reach the composition layer. GraphInterrupt and AbortError are re-thrown as control flow.

  2. Defensive addFrontmatterWarning — Wrapped validatePersistedFile in try/catch so frontmatter validation failures do not crash the run.

  3. Added helper functionsisGraphInterruptLike(), isAborted(), toolErrorToMessage().

test/index-middleware.test.ts

5 new tests covering error resilience scenarios:

  • Converts tool execution errors to ToolMessage instead of crashing
  • Preserves non-Error throws as ToolMessage
  • Re-throws GraphInterrupt errors without conversion
  • Re-throws AbortError without conversion
  • Swallows addFrontmatterWarning errors and returns original result

Test Results

Suite Result
index-middleware.test.ts 21 passed, 2 skipped (pre-existing mermaid timeout)
frontmatter-validator.test.ts 9 passed
New error resilience tests 5 passed

Checklist

  • Tests added/updated
  • No breaking changes
  • Error handling covers edge cases (GraphInterrupt, AbortError)
  • Existing tests pass

…d promise rejection crash

Any tool error during agent execution crashed the entire run via
unhandled promise rejection in the langchain tool-call transformer.

Root cause: when wrapToolCall middleware is present, tool errors get
wrapped in MiddlewareError by the composition layer. ToolNode.#handleError
then re-throws them as fatal because handleToolErrors !== true. The
createToolCallTransformer.rejects output promises that nobody catches,
leading to UnhandledPromiseRejection -> process crash.

Fix: catch tool execution errors inside the wrapToolCall middleware and
convert them to ToolMessages before they reach the composition layer.
GraphInterrupt and AbortError are re-thrown as control flow. Also add
defensive error handling to addFrontmatterWarning so validation failures
don't crash the run.

Closes langchain-ai#426
@himanshu231204 Himanshu Kumar (himanshu231204) changed the title fix: catch tool errors in wrapToolCall middleware to prevent crash (#426) fix: catch tool errors in wrapToolCall middleware to prevent crash Jul 22, 2026
@himanshu231204

Copy link
Copy Markdown
Contributor Author

Colin Francis (@colifran) Ready for review when you get a chance. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Any tool error crashes the whole run via unhandled promise rejection in langchain tool-call transformer

1 participant