LangChain Error Handling and Debugging

In Agent development, various errors are inevitable. This article sorts out common error types, debugging methods, and best practices.


Common Error Types

Error TypeTypical CauseSolution
ImportErrorProvider package not installedpip install langchain-deepseek, etc.
API Key Error.env not configured or Key invalidCheck environment variables and Key validity
Timeout ErrorNetwork issues or slow model responseSet the timeout parameter
Token Limit ExceededMessage history is too longUse trim_messages() to trim
Tool Call ErrorException inside the toolUse ToolException + handle_tool_errors
Model Return Format ErrorModel output does not meet expectationsUse structured output + handle_errors

ModelRetryMiddleware - Model Call Retry

LangChain provides built-in retry middleware:

Example

from langchain.agents.middleware import ModelRetryMiddleware
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model

# Built-in model retry middleware
# Automatically retry when model call fails
agent = create_agent(
    model=init_chat_model("deepseek:deepseek-v4-flash", timeout=30, max_retries=2),
    middleware=[
        ModelRetryMiddleware(
            max_retries=3,        # Retry up to 3 times
            backoff_factor=2.0,   # Backoff factor (2s, 4s, 8s)
        )
    ],
    system_prompt="You are EXAMPLE's assistant.",
)

ToolRetryMiddleware - Tool Call Retry

Example

from langchain.agents.middleware import ToolRetryMiddleware

agent = create_agent(
    model="deepseek:deepseek-v4-flash",
    tools=[my_tool],
    middleware=[
        ToolRetryMiddleware(
            max_retries=3,
            backoff_factor=1.5,
        )
    ],
)

The built-in RetryMiddleware and custom @wrap_model_call / @wrap_tool_call can coexist. Put the built-in middleware at the front of the middleware list as the outermost protection.


debug=True - Detailed Logs

Example

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage

# Enable debug mode to output detailed execution logs
agent = create_agent(
    model=init_chat_model("deepseek:deepseek-v4-flash"),
    debug=True,  # Enable debug logging
    system_prompt="You are EXAMPLE's assistant.",
)

# When executing, it will print:
# - Input state of each node
# - Output state of each node
# - Edge jump decisions
result = agent.invoke({
    "messages": [HumanMessage(content="Hello")]
})

Example output with debug=True:

[DEBUG] Starting graph execution
[DEBUG] Executing node: model
[DEBUG] Node 'model' input: {'messages': [HumanMessage(content='你好')]}
[DEBUG] Node 'model' output: {'messages': [AIMessage(content='你好!...')]}
[DEBUG] Edge 'model' -> '__end__': routing to __end__
[DEBUG] Graph execution complete

stream_mode="debug" - Most Detailed Debug Information

Example

# Get the most detailed information via stream_mode="debug"
for event in agent.stream(
    {"messages": [HumanMessage(content="Hello")]},
    stream_mode="debug",
):
    # event contains: node name, input, output, timestamp, task info, etc.
    print(f"[{event['type']}] {event.get('name', '')}")
    if 'input' in event:
        print(f" Input: {event['input']}")
    if 'output' in event:
        print(f" Output: {event['output']}")

Common Troubleshooting

Problem 1: The model keeps calling tools without stopping

Possible cause: The information returned by the tool is insufficient, and the model cannot determine whether the task is complete. Solutions:

  • Make the tool return more explicit information (e.g., "Task completed")
  • Set the stop condition in system_prompt
  • Use after_model to check the loop count, and jump_to="end" after exceeding the threshold

Problem 2: The model called the wrong tool or parameters

Possible cause: The tool description is unclear. Solutions:

  • Optimize the tool function's docstring
  • Use args_schema to restrict parameter ranges
  • Use a better model (e.g., deepseek-v4-pro instead of deepseek-v4-flash)

Problem 3: Conversation memory is not working

Checklist:

  • Did you pass the checkpointer parameter?
  • Did you use the same thread_id every time?
  • If using SqliteSaver, does the database file exist and is it writable?
Other Extensions