Skip to content
Go to Dashboard

错误码与重试

本页列出 WebAgent 的错误码矩阵,说明哪些可以重试、哪些要直接抛给用户、哪些要回去改代码。

所有错误返回结构一致:

json
{
  "code": "rate_limit_exceeded",
  "detail": "Per-key concurrency limit (10) reached.",
  "extra": { "limit": 10, "active": 10 }
}

HTTP 状态码告诉你类别code 字段是稳定契约——switch 在 code 上,不要在 detail 上(英文文案会随时间变)。

错误码矩阵

状态code重试?怎么处理
400bad_request改请求体。对照 OpenAPI 检查字段。
401unauthorizedkey 缺失 / 格式错 / 过期 / 撤销超过 1 小时宽限期。新建一个。
402insufficient_creditsSettings → Billing 充值,或开自动续费。
402budget_exceeded任务级 max_cost_usd 上限触发。提高额度或拆分任务。
403forbiddenkey 有效,但当前 project 不授权访问该资源。
403safety_boundary_violatedAgent 出于安全拒绝。读 extra.reason,改写指令。
404session_not_foundtask_not_foundprofile_not_foundid 错了,或资源已删除。
409conflict状态不一致(如对终态 task 调 cancel)。重读状态再决定。
422validation_errorschema 校验失败——extra.errors[] 列出有问题的字段。
429rate_limit_exceeded遵守 Retry-After;没有就指数退避。
429too_many_concurrent_sessions等手头 session 释放,或升级套餐。
5xxinternal_error同样调用,指数退避,3–5 次封顶。
(网络错)连接重置 / 超时——幂等重试。

✅ = 不需要思考就能重试。❌ = 不改东西继续报。

推荐的重试策略

python
import time, random

def with_retries(fn, *, attempts=4, base=0.5, cap=8.0):
    for i in range(attempts):
        try:
            return fn()
        except WebAgentError as e:
            if e.code not in {"rate_limit_exceeded",
                              "too_many_concurrent_sessions",
                              "internal_error"}:
                raise                          # 不可重试
            if i == attempts - 1:
                raise
            sleep_s = min(cap, base * 2**i) + random.uniform(0, 0.25)
            time.sleep(e.retry_after_seconds or sleep_s)

Python / TypeScript SDK 默认就内置了这套循环;上面的表是给你直接调 API 时用的。

幂等键(Idempotency-Key)

所有写入接口(POST /sessionsPOST /sessions/{sid}/tasksPOST /messages 等)都接受 Idempotency-Key 头:

http
POST /v1/projects/proj_demo_0001/do_anything/sessions
Idempotency-Key: 9b2f7c1e-…-uuid

24 小时内带同一个 UUID 重发,会拿到完全相同的响应(同样的 session_id、同样的状态码)——网络抖动也安全。每个逻辑动作生成一个 UUID,不是每次重试生成一个

任务执行期间的错误

Agent 执行过程中报错不一定让任务整个失败——很多是可恢复的:

  • 工具错误——通过 task.action.failed 推送;agent 自己决定重试 / 换工具 / 整体失败。
  • Captcha / 2FA——通过 task.input_request 推送;你用 POST /intervene 回答。
  • 硬上限触发——任务转 failederror.code = budget_exceededduration_exceeded,已花的 credits 仍计费。
  • 安全拒绝——任务转 failederror.code = safety_boundary_violated,被拒绝那一步不计费。

四种都通过 SSE 流 看得见。

SSE 专属故障

现象原因解决
流卡 60 s 以上网络断 / 代理缓冲Last-Event-ID: <最后一个 id> 重连。
Last-Event-ID 不生效缓冲过期(> 1 小时)GET /sessions/{sid}/tasks/{tid} 重读状态,从当前继续。
重连后事件重复at-least-once 投递id 去重(每个 task 内单调递增)。

下一步