Skip to content

[Bug]: Other first-party adapters drop ToolMessage.error too (langchain TS, aws-strands, vercel-ai-sdk, mastra) #2306

Description

@contextablemark

Describe the Bug

Follow-up to #2226, split out of the review of #2263.

#2226 and #2263 treat this as a LangGraph bug, but the same one-line omission is present in several other first-party adapters: AG-UI's ToolMessage.error is never read when an incoming tool result is converted into the target framework's tool-result shape, so a client-reported tool failure is handed to the model as a success.

integrations/langchain/typescript — same fix as #2263, verbatim. src/messages.ts:46-51:

if (message.role === "tool") {
  return new ToolMessage({
    content: message.content,
    tool_call_id: message.toolCallId,
  });
}

@langchain/core's ToolMessage has the same status: "success" | "error" field the LangGraph fix targets, and the same provider plumbing consumes it. This is a direct copy of #2263's change.

integrations/aws-strands/python — hardcoded success. src/ag_ui_strands/agent.py:234-243:

if role == "tool":
    pending_tool_results.append(
        {
            "toolResult": {
                "toolUseId": getattr(msg, "tool_call_id", "") or "",
                "content": [{"text": _coerce_text(msg.content)}],
                "status": "success",
            }
        }
    )

The Bedrock toolResult block accepts status: "success" | "error", and here it is pinned to "success" unconditionally — a failed frontend tool call is asserted to the model as having succeeded. Same shape of fix: "error" if getattr(msg, "error", None) else "success".

The same file's agui_messages_to_strands-style conversion at agent.py:198-208 also rebuilds an AG-UI ToolMessage without error, dropping the field on that path too.

integrations/vercel-ai-sdk/typescript (src/index.ts:271-281) and integrations/mastra/typescript (src/utils.ts:202-214) both build a tool-result part from toolCallId / toolName / result with no error signal at all. Whether these are fixable depends on the AI SDK version in use — v5's tool-result output supports an error-typed output — so they need a look rather than a copy-paste of the same patch.

Steps to Reproduce

Same as #2226, with the adapter swapped. For the LangChain TS adapter:

  1. Convert an AG-UI ToolMessage with error set via integrations/langchain/typescript's message conversion.
  2. Inspect the resulting ToolMessage.status.
  3. It is "success" (the default); langchain_anthropic and friends then report is_error: false to the model.

Expected Behavior

Every first-party adapter that converts an AG-UI tool message into a framework tool result should carry the failure signal across when the target framework has a slot for it. error set ⇒ the framework's error flag set.

Additional Context

  • Worth deciding as a group rather than one PR per adapter, so the adapters do not diverge on the "does the error text travel too?" question. The claude-managed-agents adapters already do carry it — integrations/claude-managed-agents/typescript/src/agent.ts:30-32 and integrations/claude-managed-agents/python/ag_ui_claude_managed_agents/agent.py:521-532 newline-join content + error into the result text and set is_error from bool(error) — so there is an in-repo precedent to standardize on.
  • [Bug]: LangGraph adapters drop ToolMessage.error, so a client-reported tool failure reaches the model as a success #2226's documentation note applies here as well: the tools concept page's "Tool Results" example omits error entirely, which is plausibly why adapter authors keep missing it.

Environment

integrations/langchain (TypeScript), integrations/aws-strands (Python),
integrations/vercel-ai-sdk (TypeScript), integrations/mastra (TypeScript), as of bb1c2afd
Related: #2226, #2263

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions