Qoder Agent SDK 分别报告任务失败、SDK 失败和进程退出。处理错误时应优先使用最具体的信号,而不是把所有非成功状态都当作异常。
Result 消息中的
未来的运行时可能增加新的 Result subtype。应用应保留兜底分支,记录未知 subtype 和
TypeScript 的
当前 qodercli 会把下列数值码归一化,并可能通过 TypeScript 和 Python 的
SDK 异常表示应用无法配置、启动、控制或继续会话,与 Agent 返回失败 Result 是两种不同情况。
Java 的模型选择回调超时不会以异常交给应用,
对于启动后发现的凭据过期,请使用
Java SDK 自定义的异常都继承非受检的
以下错误码表示会话已经终止:
关闭游标会异步关闭所属的查询或会话。完整的异常和错误码列表见 Java 异常一览。
使用 SDK 的应用通常应处理 Result 和 SDK 异常,不应直接根据进程退出码编排业务逻辑。退出码主要用于 Transport 诊断,或直接启动 qodercli 的场景。
其他退出码或终止信号可能来自操作系统、自定义运行时或子进程。TypeScript 通过
一条可用于排障的失败记录应包含:
error_code 和 qodercli 进程退出码属于两套不同的编号体系,不要用其中一套的数值匹配另一套。
推荐处理顺序
- 持续消费消息,直到 SDK 产出
result或抛出异常。 - 收到 Result 后,先检查
subtype和is_error;只有在error_code存在时,才用它选择更具体的恢复策略。 - 在整个消息迭代外捕获 SDK 异常,根据异常类型和字段诊断配置、运行时或 Transport 问题。
- 记录会话 ID、Result subtype、错误码和异常名称。默认不要记录认证信息或完整源码内容。
Result subtype
subtype | 含义 | 建议处理方式 |
|---|---|---|
success | Agent 已完成当前任务 | 读取 result,继续会话或关闭会话 |
error_during_execution | 因执行、模型、服务、认证或不可恢复的工具错误而停止 | 读取 errors;存在 error_code 时据此处理;只有瞬时故障才适合重试 |
error_max_turns | Agent 达到配置的最大轮数 | 先检查循环或被阻止的工具,确认确实需要更多轮次后再提高限制 |
errors,不要假设上表覆盖所有值。
处理 Result
TypeScript 的 SDKResultMessage.error_code 为可选的 number | string;Python 的 ResultMessage 提供可选的数值错误码。TypeScript 会原样保留 CLI 返回的 storage_insufficient 等字符串错误码,以及未知错误码。字段存在时可以据此处理,但不要通过解析面向用户的错误文本提取错误码。
Java 的 ResultMessage 没有错误码字段:outcome() 返回归一化结果 SUCCESS、ERROR 或 UNKNOWN,wireSubtype()、wireIsError() 和 errors() 对应 subtype、is_error 和 errors。需要 error_code 时,从 rawJson() 读取。
Result 错误码
当前 qodercli 会把下列数值码归一化,并可能通过 TypeScript 和 Python 的 message.error_code 返回;Java 从 ResultMessage.rawJson() 的 error_code 字段读取。该字段是可选字段;qodercli 也可能透传下表未列出的数值服务错误码。因此应保留未知值用于日志,并使用 subtype 和 errors 作为兜底。
认证与配额
| 错误码 | 含义 | 建议处理方式 |
|---|---|---|
105 | 登录态或 Access Token 已过期 | 获取有效凭据并创建新会话;注册认证过期回调 |
110 | 达到当日用量限制 | 等待用量周期重置,或检查账户限制 |
113 | 用量配额耗尽 | 检查配额和套餐状态,不要立即原样重试 |
114 | 达到免费试用账户限制 | 检查账户资格或升级选项 |
115 | 达到免费用户配额 | 等待配额恢复或检查升级选项 |
116 | 团队管理员 Credits 耗尽 | 由团队管理员补充或调整 Credits |
117 | 团队成员 Credits 耗尽 | 请团队管理员分配或补充 Credits |
118 | 个人 Credits 耗尽 | 补充 Credits,或使用仍有额度的账户 |
119 | 所选模型的免费额度已用完 | 选择可用模型、等待额度恢复或检查套餐 |
122 | Billing Group 的 Credits 达到上限 | 请账单管理员检查 Group 限制 |
请求与策略
| 错误码 | 含义 | 建议处理方式 |
|---|---|---|
406 | 因敏感内容或模型拒绝而阻止请求 | 修改任务或输入内容,不要原样重试 |
416 | 请求的范围或结构无法满足 | 查看 errors,缩小或修正请求范围 |
430 | 不支持请求的能力 | 升级到兼容的 SDK/qodercli,或改用受支持的能力 |
47902 | 达到 Agent 最大轮数 | 提高轮数前先检查循环、权限和工具失败 |
48716 | Hook 阻止 Agent 执行 | 检查对应 Hook 的决策,并修改 Hook 或任务 |
80411 | 输入内容过长 | 减少任务文本、附件或保留的上下文 |
80412 | 图片或文档数量过多 | 减少媒体附件数量后重试 |
服务与模型运行时
| 错误码 | 含义 | 建议处理方式 |
|---|---|---|
500 | 请求或网络失败 | 检查网络连接,使用有次数上限的指数退避重试 |
10408 | 请求超时 | 使用退避策略重试;反复超时时缩小任务范围 |
10500 | 模型服务内部错误 | 稍后重试;联系支持时保留会话 ID |
10605 | 模型请求正在排队 | qodercli 通常会等待并重试;如果最终 Result 仍返回此码,应稍后重试 |
SDK 异常
SDK 异常表示应用无法配置、启动、控制或继续会话,与 Agent 返回失败 Result 是两种不同情况。
| 场景 | TypeScript | Python | Java | 关键字段 |
|---|---|---|---|---|
| 未配置认证 | 带 code: "auth_not_configured" 的 Error | 带 code: "auth_not_configured" 的 Error | InvalidOptionsException | code;Java getCode() |
| PAT 环境变量不存在 | AuthAccessTokenEnvVarError | AuthAccessTokenEnvVarError | AuthenticationException | code;Java getCode() |
| Service Account 环境变量不存在 | AuthServiceAccountEnvVarError | AuthServiceAccountEnvVarError | — | code |
| 找不到或无法启动 qodercli | QoderCliProcessError | CLINotFoundError / CLIConnectionError | CliNotFoundException、RuntimeInstallException,或错误码为 CLI_START_FAILED 的 QoderException | 错误消息;TypeScript stderr;Python 路径/消息;Java getCode() |
| qodercli 意外退出 | QoderCliProcessError | ProcessError | CliProcessException;退出码 41 时为 AuthenticationException | exitCode / exit_code、stderr;TypeScript signal;Java getExitCode()、getStderrTail() |
| 模型选择回调超时 | ModelPolicyTimeoutError | ModelPolicyTimeoutError | 不抛出异常,见表后说明 | timeoutMs / timeout_ms |
| 协议版本不兼容 | ProtocolVersionMismatchError | ProtocolVersionMismatchError | ProtocolVersionMismatchException | CLI 和 SDK 的协议版本 |
| 运行时缺少所需能力 | UnsupportedCliCapabilityError | UnsupportedCliCapabilityError | UnsupportedCliCapabilityException | capability;Java capabilityState() |
| CLI 在初始化完成前返回失败结果 | QoderCliInitializationError | — | — | message、code、result |
catch 捕获不到。SDK 把错误码 MODEL_RESOLUTION_TIMEOUT 回给 CLI,并向诊断监听器发出 inbound_control_request_failed 事件,detail 含 error=MODEL_RESOLUTION_TIMEOUT。需要识别这种情况时注册 DiagnosticsListener,本轮结果按 ResultMessage.outcome() 处理,为 ERROR 时读取 errors()。
TypeScript 的 startup() 和 query.initializationResult() 在初始化完成前收到 CLI 失败 Result 时抛出 QoderCliInitializationError。message 保留 CLI 错误提示,code 保留可选的数字或字符串 error_code,result 保留完整原始结果。取消仍通过 AbortError 表达。初始化完成后的失败继续通过 Result 消息返回。
TypeScript 和 Python 共用的机器可读认证配置错误码如下:
code | 含义 |
|---|---|
auth_not_configured | 没有提供认证方式 |
auth_access_token_env_var_not_configured | 配置的 PAT 环境变量不存在 |
auth_service_account_env_var_not_configured | 配置的 Service Account 环境变量不存在 |
onAuthExpired / on_auth_expired,并用有效凭据创建新会话。Java 没有该回调,按 AuthenticationException 处理。详见 SDK 认证。
异常与错误码(Java)
Java SDK 自定义的异常都继承非受检的 QoderException,用 getCode() 取稳定的错误码。参数错误和配置错误在调用时同步抛出,例如 build() 校验失败抛出 InvalidOptionsException。启动和运行中的失败从消息游标的 hasNext() / next()、consume() 返回的 stage 或其他异步方法返回的 stage 交付;用 join() 等待时会包装成 CompletionException,用 getCause() 取出原异常。
SDK 不会自动重试,内置异常的 isRetryable() 都返回 false。常见错误码的处理方式:
| 错误码 | 处理方式 |
|---|---|
INVALID_OPTIONS | 修正配置,重试没有意义 |
AUTHENTICATION_FAILED、CLI_AUTH_FATAL | 修正凭据或账号权限,再创建新的查询或会话 |
CLI_NOT_FOUND、RUNTIME_INSTALL_FAILED、CLI_START_FAILED、UNSUPPORTED_SECURE_SECRET_TRANSPORT | 检查 CLI 路径、托管 CLI 下载和启动环境,见问题排查 |
CLI_PROCESS_FAILED | 记录 getExitCode() 和 getStderrTail() |
UNSUPPORTED_CLI_CAPABILITY | 当前 CLI 不支持所调用的功能。自行指定 CLI 时改用 SDK 托管的锁定版本,否则不使用该功能 |
SESSION_CLOSED | 资源已关闭,不要继续调用;需要时新建会话 |
MESSAGE_STREAM_ALREADY_CONSUMED | 每个消息流只能消费一次,openCursor() 和 consume() 合计只能调用一次 |
SPOOL_CAPACITY_EXCEEDED | 未消费的消息超过缓冲上限。及时读取消息流 |
QUERY_WRITE_FAILED(一次性查询的输入没有写入 CLI)、CONTROL_WRITE_FAILED(控制请求或响应没有写入 CLI)、TURN_ACCOUNTING_FAILED(轮次状态无法继续处理)、MESSAGE_DELIVERY_FAILED(一条缓冲消息无法解码)。原会话不能继续使用:关闭句柄,用 getCause() 记录原因;需要接着对话时,用原会话 ID 通过 SessionOptions.Builder.resume(String) 新建会话。
阻塞在 MessageCursor.hasNext() 或 next() 上的线程被中断时,抛出 ConsumerInterruptedException,线程的中断标志仍然保留。停止读取时关闭游标:
Java
qodercli 进程退出码
使用 SDK 的应用通常应处理 Result 和 SDK 异常,不应直接根据进程退出码编排业务逻辑。退出码主要用于 Transport 诊断,或直接启动 qodercli 的场景。
| 退出码 | 含义 |
|---|---|
0 | 进程正常退出 |
1 | 通用或未分类失败 |
41 | 认证失败;配置了认证过期回调时,SDK 也会触发该回调。Java 报告为错误码 CLI_AUTH_FATAL 的 AuthenticationException |
42 | 输入或命令行参数无效 |
44 | 致命沙箱错误 |
52 | 致命配置错误 |
53 | 致命轮数限制错误 |
54 | 致命工具执行错误 |
130 | 取消或中断 |
QoderCliProcessError.exitCode 和 .signal 暴露;Python 通过 ProcessError.exit_code 暴露可用的退出码;Java 通过 CliProcessException.getExitCode() 暴露。
日志与问题反馈
一条可用于排障的失败记录应包含:
- SDK 语言和版本
system/init消息中的 qodercli 版本(如果可用)session_id、Resultsubtype、可选error_code和errors- 异常类型、机器可读
code、进程退出码和信号 - 失败发生在初始化前、工具调用期间,还是 Result 产生后
下一步
- SDK 认证 — 配置凭据并处理过期
- 权限控制 — 了解工具拒绝和审批行为
- Hooks — 排查 Hook 阻止执行的问题
- 会话控制 — 中断和管理运行中的会话
- SDK References — 查看各语言的准确类型