langchain-ai/langchain · error · OutputParserException

{exceptions joined with '\n\n'}

Error message

{exceptions joined with '\n\n'}

What it means

Raised by parse_tool_calls when one or more raw tool calls fail parsing: each individual OutputParserException (e.g. error 189) is collected as a string, and all are joined with blank lines into a single OutputParserException. This aggregates multi-tool-call failures so you see every broken argument payload at once.

Source

Thrown at libs/core/langchain_core/output_parsers/openai_tools.py:135

        The parsed tool calls.

    Raises:
        OutputParserException: If any of the tool calls are not valid JSON.
    """
    final_tools: list[dict[str, Any]] = []
    exceptions = []
    for tool_call in raw_tool_calls:
        try:
            parsed = parse_tool_call(
                tool_call, partial=partial, strict=strict, return_id=return_id
            )
            if parsed:
                final_tools.append(parsed)
        except OutputParserException as e:
            exceptions.append(str(e))
            continue
    if exceptions:
        raise OutputParserException("\n\n".join(exceptions))
    return final_tools


class JsonOutputToolsParser(BaseCumulativeTransformOutputParser[Any]):
    """Parse tools from OpenAI response."""

    strict: bool = False
    """Whether to allow non-JSON-compliant strings.

    See: https://docs.python.org/3/library/json.html#encoders-and-decoders

    Useful when the parsed output may include unicode characters or new lines.
    """

    return_id: bool = False
    """Whether to return the tool call id."""

    first_tool_only: bool = False

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Read the combined message to identify which tool call(s) failed, then fix the cause (usually max_tokens truncation or model JSON quality)
  2. Increase max_tokens and retry the request
  3. Use the higher-level AIMessage.tool_calls / invalid_tool_calls surface, which isolates bad calls instead of raising, when you want per-call resilience

Example fix

# before
calls = parse_tool_calls(message.additional_kwargs["tool_calls"])  # raises if any call is bad

# after
for tc, itc in zip(message.tool_calls, message.invalid_tool_calls or []):
    if itc:
        log.warning("bad tool call", itc.error)
# message.tool_calls contains only the successfully parsed calls
Defensive patterns

Strategy: fallback

Try / catch

try:
    calls = parse_tool_calls(raw_tool_calls)
except OutputParserException as e:
    # e.message lists every failure; fall back to per-call parsing
    calls = []
    for rc in raw_tool_calls:
        try:
            calls.append(parse_tool_call(rc))
        except OutputParserException:
            continue

Prevention

When it happens

Trigger: A model response containing multiple tool_calls where at least one has invalid JSON arguments; parse_tool_calls(raw_tool_calls, partial=False) on responses from models with unreliable JSON emission.

Common situations: Parallel tool calling with one malformed payload; token-limit truncation affecting one of several calls; parsing cached/replayed raw responses captured from older API formats.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/d785cfca5425a9da. Report an issue: GitHub.