Tool error is automatically handled by langchain agent

Hello, I am debugging my code, I want get error informations when a error occured. I didn’t add any middleware, but I got a message below for a tool

Error invoking tool 'planner' with kwargs..., Please fix the error and try again

There is no such text in my code, so this may come from langchain or langgraph. How to make the agent does not handle the tool errors at all ?

That message comes from LangGraph’s ToolNode, which create_agent uses internally. It is not from your code or from middleware you added.

The Error invoking tool ... Please fix the error and try again text usually means the model sent invalid arguments for planner (schema / validation failed). The framework turns that into a ToolMessage with status="error" so the model can retry. Exceptions inside the tool body are not swallowed by default, only this kind of invocation error is handled automatically.

To see the details:

from langchain.messages import ToolMessage

for msg in result["messages"]:
    if isinstance(msg, ToolMessage) and msg.status == "error":
        print(msg.content)

To stop the agent from handling it (fail the run instead of returning an error message to the model), use middleware and re-raise on error tool messages:

from langchain.agents.middleware import wrap_tool_call
from langchain.messages import ToolMessage

@wrap_tool_call
def fail_on_tool_error(request, handler):
    msg = handler(request)
    if isinstance(msg, ToolMessage) and msg.status == "error":
        raise RuntimeError(msg.content)
    return msg


agent = create_agent(
    model="openai:gpt-5.5",
    tools=[],
    middleware=[handle_tool_errors],
)

Docs: Tools – error handling

I did notice a similar ssue today actually, it seems to be a behaviour change. Normally errors are caught only if the ToolErrorMiddleware ( ToolErrorMiddleware | langchain | LangChain Reference ) (or any custom implementation) is set, but nowadays I experience the reverse behaviour.

See this test in a demo project I’ve implemented today, it should not pass as is without a ToolErrorMiddleware, yet it does.

From ToolErrorMiddleware docs:
“exceptions you do not return content for propagate unchanged, so arbitrary internal exceptions are never serialized to the model or end user unless you choose to surface them.”

Can you please tell me the version of Langchain you are using?

It should be 1.4.7 according to my uv.lock (langchain-early-return/uv.lock at 59656635d1289d94d795bcd83738d0a72d7a3dcc · lbke/langchain-early-return · GitHub), I’ve created a the project last week.

Okay let me check, will get back to you @eric-burel @MSJavaScript if this is happening in newer version, but for now workaround should work @MSJavaScript .

@eric-burel
I checked this on current langchain / 1.4.x.

Two different things:

  1. ToolNode inside create_agent turns bad tool args / validation (invocation) errors into error ToolMessages, including the "Error invoking tool ... Please fix the error and try again" text. That’s been the default since LangChain 1.0, not something new in 1.4.7, and it’s not ToolErrorMiddleware.

  2. ToolErrorMiddleware: opt-in only for exceptions inside the tool body. Without it, those still propagate and fail the run.

Your test_errored_tool can pass without that middleware because the tool takes Runtime; the failure is often invocation/validation, surfaced as an error ToolMessage before your raise ValueError(...) runs. Your EarlyReturnMiddleware already assumes that (ToolMessage.status == "error").

So this isn’t a recent behavior flip in 1.4.7, it’s the intended split: invocation errors → automatic observations; execution errors → propagate unless you opt in.

@eric-burel I hope this clears up, if not then open a new thread and I would love to clarify more.