学习笔记 · Obsidian
LangChain TypeScript:错误与排查
先分类,再重试
| 类别 | 典型错误 | 默认处理 |
|---|---|---|
| 输入/协议 | INVALID_PROMPT_INPUT、MESSAGE_COERCION_FAILURE、INVALID_TOOL_RESULTS | 修代码或数据,不重试相同请求 |
| 身份/配置 | MODEL_AUTHENTICATION、MODEL_NOT_FOUND | 修 secret、model/endpoint/proxy,不盲重试 |
| 暂时容量 | MODEL_RATE_LIMIT | 遵循 retry-after、退避+jitter、并发限制/fallback |
| 输出契约 | OUTPUT_PARSING_FAILURE | 改 structured output/schema/prompt/model,有限修复重试 |
错误处理的目标不是“让异常消失”,而是保留原始 cause、provider status/request ID、run/tool ID 和可操作上下文,同时向用户返回脱敏、稳定的错误码。
INVALID_PROMPT_INPUT
Prompt template 收到缺失或非法变量。常见陷阱是把 JSON 直接写进 f-string 风格模板:单个 {} 会被解析为变量,应按模板规则转义;若想输出单花括号用 {{/}},需要字面双花括号则继续加倍。
还要检查:
- template 声明的变量与 invoke 对象是否一致;
MessagesPlaceholder是否收到 message 数组/message-like objects;- shorthand placeholder 是否把变量写成
"{messages}"; - 从 Hub 拉取的 prompt 版本与调用代码是否匹配。
用单元测试直接 invoke prompt,并在脱敏后记录实际 keys。不要把完整用户数据或 secret 写进日志。
INVALID_TOOL_RESULTS:JS 专有重点
该错误当前标记为 langchainjs 使用。协议不变量:一个含 tool_calls 的 AIMessage 后,必须为每个 call 提供恰好一个 matching ToolMessage.tool_call_id。
失败形态:
- 两个 tool calls 只返回一个结果;
- 同一 ID 重复两个结果;
- ToolMessage ID 不存在;
- 没有前置 tool call 的孤立 ToolMessage;
- trim/summarize/branch 恢复时破坏了 call/result 配对。
并行工具执行应按 ID 建 Map 做全集/唯一性校验,不能依赖完成顺序。错误/超时工具也需要产生与该 ID 对应的受控结果,或让整个 turn 明确失败,不能悄悄丢掉。
MESSAGE_COERCION_FAILURE
模型输入必须是 LangChain message class 数组或支持的 message-like 格式。常见原因:
- 把整个 message array
JSON.stringify成一条字符串; role/content键错误或 content block 结构非法;- 数据库反序列化后 class/prototype 丢失,却仍按 class 方法使用;
- 跨 Python/JS 服务时混入另一语言的内部对象格式;
undefined、循环对象或 UI state 被直接塞入 messages。
在进入 model 前记录每条 message 的 type/role、content kind 和 ID,而非完整内容。优先使用明确的 HumanMessage/AIMessage/ToolMessage 或官方 message-like shape。
本页正文仍写着 TODO: Add JS example,说明官方错误文档尚不完整;具体可接受 shape 应查当前 JS Messages API 和类型定义。
MODEL_AUTHENTICATION
Provider 拒绝凭证。检查:环境变量名和值、secret 是否加载到实际 server process、key scope/expiry、proxy/base URL 的认证方式、部署环境是否覆盖本地 .env。
文档展示显式 apiKey 只是用于隔离环境加载问题;生产不要硬编码或打印 key。修复后应轮换曾泄漏的凭证,并用最小权限。401/403 通常不是普通 transient retry。
MODEL_NOT_FOUND
Model identifier 不被 provider 识别:拼写/命名空间错误、账号无权使用、地区不支持,或 proxy/wrapper 限制/改写允许的 model names。核对当前 provider model list 和实际 endpoint;不要根据别的 provider 示例猜名字。
模型退役是配置变化,应有受控 fallback 和回归 eval;不能在错误时随机换模型后继续高风险副作用。
MODEL_RATE_LIMIT
请求数/token/并发超过 provider 配额。生产方案是组合:
- 全局 + tenant/user rate limiter;
- 遵循 provider retry-after,指数退避+jitter和最大次数/总时限;
- queue/backpressure,限制 agent 并行 tool/model fan-out;
- 对安全、可复用查询做隔离 cache;
- 预算路由、较小模型或已验证 provider fallback;
- 容量监控、配额申请和降级响应。
“多个 provider 分流”会带来数据驻留、模型行为、schema、成本和合规差异,必须先做契约/eval,不是无成本开关。
OUTPUT_PARSING_FAILURE
Output parser 无法解析模型文本。旧 agents/chains 可能内部使用 parser,因此即使代码未显式创建也会看到该错误。优先迁移到 provider native structured output 或 tool calling,并用 Zod/Standard/JSON Schema 验证;其次才是加强 format prompt 或换更适合的模型。
修复重试要把验证错误以受控形式反馈,并设置次数/总时限。不要用正则“抢救”任意半结构化 JSON 后直接进入关键业务。页面把 output parser reference 链到 Python,也是语言模板残留。
与 MCP/工具错误的组合
MCP JS adapter 遇到 isError: true 会抛 ToolException,不会自动生成 failed ToolMessage。若在 agent loop 中捕获它,仍要保证:
- 与原 tool call ID 的协议关系完整;
- 返回给模型的错误不含 stack、secret、内部 URL/SQL;
- 只对明确 transient、幂等操作有限重试;
- trace 保留 provider/MCP request ID 与分类后的 cause。
标准排查流程
- 固定并记录 Node、
langchain、core、LangGraph、provider/MCP 包版本。 - 用最小输入重现,区分 prompt/message/tool/model/provider 层。
- 查 LangSmith trace 的失败 node、call ID、重试与原始 status,先脱敏。
- 用
fakeModel复现协议/中间件逻辑;真实 provider integration 验证外部契约。 - 对照当前 JavaScript API Reference、changelog 和 provider 官方状态页。
- 修复后加入回归测试或 dataset/eval,而不是只重跑一次成功。
逐页覆盖
| 错误页 | 核心结论 |
|---|---|
| INVALID_PROMPT_INPUT | 变量缺失、花括号转义、MessagesPlaceholder 和 Hub prompt 隔离测试。 |
| INVALID_TOOL_RESULTS | JS 特有协议检查;tool call 与 ToolMessage ID 必须一一对应。 |
| MESSAGE_COERCION_FAILURE | 只传支持的 message/class-like 格式;页面 JS 示例仍是 TODO。 |
| MODEL_AUTHENTICATION | key/env/proxy 认证排查;显式 key 仅诊断,不硬编码。 |
| MODEL_NOT_FOUND | model ID、账号/地区和 proxy allowlist。 |
| MODEL_RATE_LIMIT | limiter、cache、queue、退避、provider fallback 与容量治理。 |
| OUTPUT_PARSING_FAILURE | 优先 structured output/tool calling,有限修复重试;旧 classic 可能内部触发。 |
文档路由边界
/oss/javascript/common-errors 是栏外聚合页,链接到以上 7 个 /langchain/errors/... 正文;/oss/javascript/langchain/errors 与 .md 聚合路径当前均为 404。因此 sources 只记录 7 个可达错误正文,聚合页放在 related_sources,并在覆盖统计中区分栏内路由与栏外发现入口。