LangGraph 错误码完全指南:32 个高频错误中文解读与解决方案
LangGraph 32 个高频错误码完整中文解读,含 GraphRecursionError、InvalidUpdateError、CheckpointNotFound 等典型错误的根因分析、排查流程图、代码示例。
LangGraph 错误码完全指南:32 个高频错误中文解读与解决方案
本文基于 LangGraph v0.6.11 版本,错误码持续更新。 参考开源项目:langchain-ai/langgraph(MIT License)。 中文译注版权归裕普网络有限公司所有。
错误码分类导航
| 子模块 | 高频错误数 | 长尾错误数 | 跳转 |
|---|---|---|---|
langgraph.errors | 9 | 1 | → 查看 |
langgraph.checkpoint | 1 | 4 | → 查看 |
| Graph state(state 字段相关) | 2 | 4 | → 查看 |
| LLM / API | 0 | 3 | → 查看 |
| Routing / Edge | 0 | 3 | → 查看 |
| Pregel / Concurrency | 0 | 3 | → 查看 |
| Tools / Function | 0 | 2 | → 查看 |
一、langgraph.errors 子模块(高频错误)
GraphRecursionError
错误现象:程序抛出 GraphRecursionError: Recursion limit reached,图执行中断。
根因:图的执行步数超过了 recursion_limit(默认 25 步)。最常见的原因是条件边逻辑有 bug,导致图在几个节点之间循环。
解决方案:
from langgraph.graph import StateGraph, END
class State(TypedDict):
step_count: int
output: str
def step(state: State) -> dict:
return {"step_count": state["step_count"] + 1}
def should_continue(state: State) -> str:
if state["step_count"] >= 5:
return "end"
return "continue"
graph = StateGraph(State)
graph.add_node("step", step)
graph.add_conditional_edges("step", should_continue, {
"continue": "step",
"end": END
})
# 关键:设置 recursion_limit
graph = graph.compile(recursion_limit=50)
排查技巧:在条件边函数里加
print(f"step={state['step_count']} route={route}")观察路由循环。
InvalidUpdateError
错误现象:InvalidUpdateError: Invalid update at node xxx,schema 校验失败。
根因:节点函数返回的 dict 包含了 State schema 中未声明的字段,或字段类型与 TypedDict / Pydantic 定义不匹配。
解决方案:
from typing import TypedDict
class OrderState(TypedDict):
order_id: str
status: str
total: float
# 错误写法:返回了 schema 中没有的字段
def bad_node(state: OrderState) -> dict:
return {"order_id": state["order_id"], "status": "paid",
"total": 99.0, "extra_field": "oops"} # InvalidUpdateError!
# 正确写法:只返回 schema 中有的字段
def good_node(state: OrderState) -> dict:
return {"status": "paid", "total": 99.0}
GraphInterrupt
错误现象:执行暂停,抛出 GraphInterrupt(注意:这是正常流程,不是错误)。
根因:代码中显式调用了 interrupt(value),用于 Human-in-the-loop 场景。
解决方案:用 Command(resume=value) 恢复执行:
from langgraph.types import interrupt, Command
def approval_node(state: State) -> Command:
decision = interrupt("请审批该请求")
if decision["approved"]:
return Command(goto="process", update={"status": "approved"})
return Command(goto="reject", update={"status": "rejected"})
NodeInterrupt
错误现象:节点内部抛出 NodeInterrupt,执行暂停在该节点。
根因:节点函数内部调用了 interrupt(),且未提供 resume 值。
解决方案:与 GraphInterrupt 相同,使用 Command(resume=...) 恢复。确保上游有 interrupt_before 或 interrupt_after 配置。
NodeCancelledError
错误现象:NodeCancelledError: Node execution was cancelled。
根因:节点执行被外部中止(任务取消 / 服务 shutdown / 超时 kill)。
解决方案:
import signal
def timeout_handler(signum, frame):
raise TimeoutError("Node execution timed out")
# 在节点函数中设置超时
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(25) # 25 秒超时
try:
result = long_running_task()
finally:
signal.alarm(0)
NodeTimeoutError
错误现象:NodeTimeoutError: Node timed out after 30s。
根因:节点执行时间超过配置的 timeout(默认 30 秒)。常见于调用外部 API 或大模型推理。
解决方案:
import httpx
async def call_external_api(state: State, timeout: float = 60.0) -> dict:
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.post("https://api.example.com/process", json=state)
return {"result": resp.json()}
# 或在 graph.compile 时设置节点级 timeout
graph = graph.compile(
checkpointer=memory,
node_config={"slow_node": {"timeout": 120}}
)
ParentCommand
错误现象:ParentCommand: Command received from subgraph。
根因:subgraph 内部通过 Command(goto=...) 向 parent graph 发送了跨层通信指令。这是 LangGraph 的正常机制,但如果 parent 没有正确处理会抛出异常。
解决方案:确保 parent graph 中对应的节点能处理 subgraph 返回的 Command:
# parent graph 中
graph.add_edge("subgraph_node", "handle_result")
def handle_result(state: State) -> dict:
# subgraph 可能通过 Command 返回更新
return state
EmptyInputError
错误现象:EmptyInputError: Input is empty or all fields are None。
根因:app.invoke({}) 传入的 state 为空字典,或所有必填字段都为 None。
解决方案:
from pydantic import ValidationError
class RequiredState(TypedDict):
user_input: str # 必填
# 错误写法
result = app.invoke({}) # EmptyInputError
# 正确写法:提供必填字段
result = app.invoke({"user_input": "你好"})
TaskNotFound
错误现象:TaskNotFound: task_id xxx not found in state。
根因:在多任务并发场景中,引用了 state 中不存在的 task_id。
解决方案:确保 task_id 的创建和引用在同一个 graph 执行周期内,或在 checkpointer 中正确恢复。
GraphDrained
错误现象:GraphDrained: All tasks consumed, graph is drained。
根因:图排空(所有任务消费完毕),通常发生在 Signal GEN = SIGTERM 触发的优雅退出时。
解决方案:这是正常退出信号,无需处理。如需重启,重新 invoke 即可。
二、langgraph.checkpoint 子模块
EmptyChannelError
错误现象:EmptyChannelError: Channel is empty,checkpoint 写入失败。
根因:某个 channel 在本轮执行中没有产生任何更新(值未变化),写 checkpoint 时触发空值校验。
解决方案:
from langgraph.channels import LastValue
# 使用 LastValue channel 允许空值覆盖
graph.add_node("update", update_node, output=LastValue("field"))
CheckpointNotFound
错误现象:CheckpointNotFound: thread_id xxx not found in storage。
根因:指定的 thread_id 在 checkpointer 存储中不存在,可能原因:
- thread_id 拼写错误
- checkpoint 已被清理(TTL 过期)
- 数据库连接的是不同的环境(dev / prod 混淆)
解决方案:
# 确认 thread_id 格式
config = {"configurable": {"thread_id": "user-123-session-1"}}
# 检查 checkpointer 连接
from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string("postgresql://user:pass@host/db")
print(checkpointer.conn.info) # 确认连接的数据库
SerializationError-checkpoint
错误现象:SerializationError: Failed to serialize checkpoint(msgpack / pickle 错误)。
根因:State 中包含不可序列化的对象(如 datetime、自定义类、函数)。
解决方案:State 中只使用基本类型(str / int / float / bool / list / dict):
from datetime import datetime
from pydantic import BaseModel
# 错误:State 中包含 datetime
class BadState(TypedDict):
created_at: datetime # msgpack 无法序列化
# 正确:转成 ISO 字符串
class GoodState(TypedDict):
created_at: str # "2026-09-08T12:00:00"
CheckpointerConnectionError
错误现象:CheckpointerConnectionError: could not connect to postgres。
根因:Postgres / Sqlite checkpointer 连接失败。
解决方案:
# 检查 Postgres 服务状态
pg_isready -h localhost -p 5432
# 检查连接字符串
echo $POSTGRES_CONNECTION_STRING
# 期望:postgresql://user:pass@host:5432/dbname
BinaryOperatorAggregateError
错误现象:BinaryOperatorAggregateError: duplicate keys in state aggregator。
根因:多个节点同时更新同一个字段,且 reducer 不支持合并(如两个节点都 return {"messages": [...]} 但 messages 使用了字典合并而非列表追加)。
解决方案:使用 Annotated[list, add_messages] 定义消息字段:
from typing import Annotated
from langgraph.graph.message import add_messages
class State(TypedDict):
# 正确:多个节点可以安全追加消息
messages: Annotated[list, add_messages]
三、Graph state 子模块(本项目实战高频)
ImportError-version-mismatch
错误现象:ImportError: cannot import name 'xxx' from 'langgraph'。
根因:langgraph 和 langchain-core 版本不匹配。LangGraph 0.6.11 要求 langchain-core>=0.3.0。
解决方案:
# 统一升级到兼容版本
pip install --upgrade langgraph==0.6.11 langchain-core>=0.3.0
# 验证版本
python3 -c "import langgraph, langchain_core; print(langgraph.__version__, langchain_core.__version__)"
InvalidUpdateError-state-field-mismatch
错误现象:InvalidUpdateError: Field type mismatch for 'xxx'。
根因:State TypedDict 字段类型与实际返回值不符(如字段定义 int,返回了 str)。
解决方案:
from typing import TypedDict
class State(TypedDict):
count: int
# 错误:count 应该是 int,但返回了 str
def bad_node(state: State) -> dict:
return {"count": "10"} # InvalidUpdateError
# 正确:类型匹配
def good_node(state: State) -> dict:
return {"count": 10}
KeyError-state-field-missing
错误现象:KeyError: 'field_name'。
根因:节点函数访问了 state 中不存在的字段。常见于 TypedDict 拼写错误或字段被条件跳过。
解决方案:使用 .get() 安全访问,或确保所有路径都初始化该字段:
def safe_node(state: State) -> dict:
# 错误写法
value = state["missing_field"] # KeyError
# 正确写法:用 get 提供默认值
value = state.get("missing_field", "default")
return {"field": value}
TypeError-node-signature
错误现象:TypeError: node() missing 1 required positional argument: 'state'。
根因:节点函数签名错误,缺少 state 参数或参数名不匹配。
解决方案:
# 错误写法
def my_node(): # 缺少 state 参数
return {"result": "ok"}
# 正确写法
def my_node(state: State) -> dict:
return {"result": state.get("input", "")}
ValidationError-pydantic-state
错误现象:ValidationError: value is not a valid integer(Pydantic 校验失败)。
根因:State 使用 Pydantic BaseModel 定义,但节点返回值不符合字段类型或约束。
解决方案:
from pydantic import BaseModel, Field
class State(BaseModel):
name: str = Field(min_length=1, max_length=100)
age: int = Field(ge=0, le=150)
# 确保节点返回符合 Pydantic 约束
def good_node(state: State) -> dict:
return {"name": state.name.strip(), "age": state.age}
StateGraphBuildError
错误现象:StateGraphBuildError: Graph structure is invalid。
根因:StateGraph 构建期错误,常见原因:
- 节点未定义就引用
- 缺少入口点
- 存在不可达节点
解决方案:
from langgraph.graph import StateGraph, END
graph = StateGraph(State)
# 错误:add_edge 引用了不存在的节点
# graph.add_edge("unknown_node", END) # StateGraphBuildError
# 正确:先 add_node,再 add_edge
graph.add_node("real_node", real_function)
graph.add_edge("real_node", END)
graph.set_entry_point("real_node")
四、LLM / API 子模块
TimeoutError-llm-call
错误现象:TimeoutError: Request timed out after 60s。
根因:LLM API 调用超时。原因可能是网络延迟、模型服务繁忙、prompt 过长。
解决方案:
import httpx
client = httpx.AsyncClient(timeout=httpx.Timeout(120.0, connect=10.0))
resp = await client.post(
"https://api.minimaxi.com/v1/chat/completions",
json={"model": "MiniMax-M2.7", "messages": [...]},
headers={"Authorization": f"Bearer {api_key}"}
)
RetryExhausted
错误现象:RetryExhausted: Max retries exceeded。
根因:LLM API 连续多次调用失败(网络抖动 / 限流 / 服务不可用),重试耗尽。
解决方案:
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(min=1, max=10))
def call_llm_with_retry(prompt: str) -> str:
return llm.invoke(prompt).content
MessageConversionError
错误现象:MessageConversionError: Failed to convert messages。
根因:LangChain 内部消息格式与 OpenAI / MiniMax API 格式不兼容,常见于混合使用不同厂商的 message 格式。
解决方案:统一使用 langchain_core.messages 标准格式:
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
messages = [
SystemMessage(content="你是一个有帮助的助手。"),
HumanMessage(content="LangGraph 怎么入门?"),
AIMessage(content="可以从官方 quickstart 开始..."),
HumanMessage(content="能给我一个代码示例吗?"),
]
# LangChain 会自动转换为目标 API 的格式
五、Routing / Edge 子模块
ConditionalEdgeMissingRoute
错误现象:ConditionalEdgeMissingRoute: No route found for 'xxx'。
根因:条件边函数返回了一个不在路由映射表中的值。
解决方案:
# 错误写法
def route(state: State) -> str:
return "unknown_destination" # 不在映射表中
graph.add_conditional_edges("node", route, {
"tech": "tech_agent",
"biz": "biz_agent"
# "unknown_destination" 缺失!
})
# 正确写法:覆盖所有可能返回值
graph.add_conditional_edges("node", route, {
"tech": "tech_agent",
"biz": "biz_agent",
"unknown_destination": "fallback_agent",
"END": END
})
SubgraphInterruptError
错误现象:SubgraphInterruptError: Interrupt in subgraph not handled。
根因:subgraph 内部触发了 interrupt(),但 parent graph 没有配置对应的 interrupt_before / interrupt_after。
解决方案:
# parent graph 中,允许 subgraph 在 "approval" 节点前中断
graph.add_node("subgraph", subgraph_app, interrupt_before=["approval"])
StreamConsumerError
错误现象:StreamConsumerError: Generator was not fully consumed。
根因:调用 graph.stream() 时,没有迭代完整个 generator 就提前退出了(如 break 或 return)。
解决方案:
# 错误写法
for event in app.stream(input):
if some_condition:
break # generator 未消费完,抛出 StreamConsumerError
# 正确写法:消费完整 generator,或使用 list() 缓存
events = list(app.stream(input))
for event in events:
process(event)
六、Pregel / Concurrency 子模块
RecursionLimitHit
错误现象:RecursionLimitHit: Pregel recursion limit exceeded。
根因:与 GraphRecursionError 类似,但发生在 Pregel 运行时层。Pregel 是 LangGraph 底层的 BSP(Bulk Synchronous Parallel)执行引擎。
解决方案:与 GraphRecursionError 相同——检查条件边环路,避免无限循环。
PregelTimeoutError
错误现象:PregelTimeoutError: Pregel execution timed out。
根因:Pregel 整体执行超时(包括所有节点执行 + 调度总时长)。通常发生在图非常复杂或某个节点阻塞时。
解决方案:
# 增大超时配置
app = graph.compile(
checkpointer=memory,
config={"recursion_limit": 100, "timeout": 300}
)
AsyncEventLoopError
错误现象:AsyncEventLoopError: async function called from sync context。
根因:在同步 pytest fixture 中直接调用 async 函数,或在 sync Playwright 测试中调用 async LangGraph 方法。
解决方案:统一使用 asyncio.run() 或 anyio:
import asyncio
# 正确:在 sync 函数中运行 async 代码
def sync_wrapper():
result = asyncio.run(async_langgraph_call())
return result
七、Tools / Function 子模块
ToolNotFound
错误现象:ToolNotFound: tool 'xxx' not found。
根因:tool_calls 引用的工具名称不在已绑定的工具列表中。
解决方案:
from langchain_core.tools import tool
@tool
def search(query: str) -> str:
"""搜索网页。"""
return f"结果:{query}"
# 绑定工具时确保名称一致
llm_with_tools = llm.bind_tools([search])
# tool_calls 中的 name 必须匹配 @tool 装饰的函数名
# {"name": "search", "arguments": {"query": "LangGraph"}} ✓
# {"name": "web_search", ...} ✘ ToolNotFound
ConfigNotFoundError
错误现象:ConfigNotFoundError: RunnableConfig missing 'xxx'。
根因:RunnableConfig 中缺少必要字段(如 configurable["thread_id"])。
解决方案:
# 错误写法
app.invoke({"messages": [...]}) # 缺少 thread_id
# 正确写法
config = {
"configurable": {
"thread_id": "user-123",
"checkpoint_ns": "default"
}
}
app.invoke({"messages": [...]}, config=config)
八、常见排查流程图
流程图(Mermaid 语法,知乎支持)
flowchart TD
A[程序抛出异常] --> B{异常类型}
B -->|GraphRecursionError| C[检查条件边环路<br/>增大 recursion_limit]
B -->|InvalidUpdateError| D[检查 Node 返回值<br/>对齐 State schema]
B -->|NodeTimeoutError| E[增大 timeout<br/>改用异步节点]
B -->|CheckpointNotFound| F[检查 thread_id<br/>确认 checkpointer 连接]
B -->|CheckpointerConnectionError| G[检查 Postgres/Sqlite<br/>服务状态]
B -->|其他错误| H[查阅完整错误码库<br/>errors-zh/INDEX.md]
C --> I[重新运行验证]
D --> I
E --> I
F --> I
G --> I
H --> I
I --> J{是否解决}
J -->|否| K[搜索 GitHub Issues<br/>langchain-ai/langgraph]
J -->|是| L[✅ 问题已解决]
文字版流程图(公众号不支持 Mermaid)
- 程序抛出异常 → 先看异常类型(类名)
- GraphRecursionError → 检查条件边是否形成环路 → 增大
recursion_limit→ 重新运行 - InvalidUpdateError → 检查抛出异常的 Node → 对比返回值与 State schema → 修正字段名/类型 → 重新运行
- NodeTimeoutError → 检查该 Node 是否调用外部 API → 增大
timeout或改用异步 → 重新运行 - CheckpointNotFound / CheckpointerConnectionError → 检查
thread_id是否正确 → 检查 Postgres/Sqlite 连接 → 重新运行 - 其他错误 → 查阅完整错误码库
../errors-zh/INDEX.md→ 搜索 GitHub Issues - 仍未解决 → 在 LangGraph GitHub Discussions 提问
九、免责声明
本文基于 LangGraph 0.6.11 版本编写,错误码及其解决方案可能随版本迭代而变化。LangGraph 迭代速度较快,请以 官方文档 和 官方 GitHub 仓库 为准。
完整错误码库(32 个错误码,含详细代码示例)见交付包内 errors-zh/INDEX.md。
资源与声明
- 原项目:langchain-ai/langgraph
- 原项目许可证:MIT License(本店交付包内
LICENSES/ORIGINAL_LICENSE附完整原文) - 关于本店:本店提供「中文本地化增强包 / 打包整理服务」——包含本文涉及的 32 条错误码完整中文库(
errors-zh/)、中文文档与场景 demo。增强包为本店原创整理工作,与原项目官方无关联;原项目本身可从其官方渠道免费获取。 - 基于 LangGraph v0.6.11(commit
dc0ee40)整理,转载请注明原项目出处。
本文由裕普智汇 AI 智能体工厂整理发布。转载请注明出处。