Skip to content

错误码参考

JarvisClaw API 所有服务的完整错误码参考。包括 HTTP 状态码、x402 支付错误和服务特定错误码。

基础 URL: https://api.jarvisclaw.ai/v1

HTTP 状态码

状态码名称描述解决方案
400Bad Request请求体格式错误或缺少必需参数。检查请求格式和必填字段。
401UnauthorizedAPI Key 无效或缺失。验证你的 API Key 是否正确且激活。
402Payment Required需要 x402 支付或 USDC 余额不足。充值 USDC 钱包或检查支付签名。
403ForbiddenAPI Key 缺少该资源的权限。在控制台检查 Key 权限。
404Not Found端点或资源不存在。验证 URL 路径是否正确。
429Rate Limited时间窗口内请求过多。退避并在 Retry-After 头指定时间后重试。
500Internal Server Error服务器意外故障。指数退避重试;持续则联系支持。
502Bad Gateway上游供应商不可用。重试;供应商可能暂时宕机。
503Service Unavailable服务过载或维护中。等待几秒后重试。

错误响应体结构

有两种结构在流通,请都做兼容处理。

OpenAI 兼容的 relay 端点/v1/chat/completions/v1/messages/v1/images/*/v1/audio/* 等):

json
{ "error": { "message": "...", "type": "...", "code": "..." } }

AIP、钱包与 marketplace 端点:

json
{ "error": "可读的错误消息" }

两个 SDK 都做了归一化 —— Python 的 APIError.message 和 Go 的 APIError.Message 会读取实际 到达的那种形态,原始响应体在 .body / .Body 上。

不要按错误码字符串分支

只有 relay 路径会返回 code,且取值取决于上游供应商返回了什么。AIP 与钱包端点只返回一个裸消息 字符串,完全没有 code。请按 HTTP 状态码和错误类型分支,把 code 当作诊断文本。

x402 支付失败

支付问题会以带 x402 报价体的 402 出现,或以携带 facilitator 拒绝原因的 402/502 出现。 常见原因:

原因表现解决方案
USDC 余额不足付费重试时返回 402向钱包充值(Base 或 Solana)
签名不匹配facilitator 校验失败确认私钥对应 from 地址
Nonce 重用被重放保护拒绝SDK 每次尝试都生成新的随机 nonce
授权过期超过 maxTimeoutSeconds(300 秒)后被拒重新签名重试;SDK 会自动处理
金额不匹配校验阶段被拒严格按 402 中的 amount 签名,不要取整
网络不受支持accepts 中没有可用选项使用 Base(eip155:8453)或 Solana 主网
Solana ATA 缺失Solana 路径被跳过先接收一笔 USDC 转账以初始化代币账户
无法定价503 price_unavailable上游价格探测失败,稍后重试

只有在网关已知 fee payer 时才会公布 Solana 选项;否则 accepts 只列 Base。详见 Agent 支付 (x402)

常见失败场景

场景状态码说明
未知或已下线的模型400查询 GET /v1/models;智能路由别名必须带 auto/ 前缀
超出上下文窗口400精简历史或换用更大上下文的模型
内容过滤400 / 任务 failed异步任务会返回 status: "failed"retryable: false
上游供应商错误502重试,或改用其他模型
触达并发上限429Marketplace 服务对并发请求数有上限
异步任务仍在执行200,status: "in_progress"继续轮询直到 completedfailed

代码示例

bash
# 检查 HTTP 状态和错误体
curl -s -w "\nHTTP_STATUS:%{http_code}" \
  https://api.jarvisclaw.ai/v1/chat/completions \
  -H "Authorization: Bearer $JARVISCLAW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hello"}]}' \
| tee >(tail -1 | grep -o "HTTP_STATUS:[0-9]*") \
| head -n -1 | jq .

# 错误时响应体将包含:
# { "error": { "code": "invalid_model", "message": "..." } }
# 或 x402 错误:
# { "error": { "code": "insufficient_balance", "message": "..." } }
python
import time

from jarvisclaw import (
    OpenAI,
    APIError,
    AuthenticationError,
    InsufficientBalanceError,
    JarvisClawError,
    RateLimitError,
)

# OpenAI 是兼容入口;ChatClient / JarvisClaw 用法相同。
client = OpenAI(api_key="sk-your-api-key")

def chat_with_retry(messages, model="openai/gpt-4o-mini", max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model=model,
                messages=messages,
            )

        except AuthenticationError as e:
            # 401 — API Key 无效,无需重试
            print(f"认证失败: {e.message}")
            raise

        except InsufficientBalanceError as e:
            # 402 — USDC 不足;充值后手动重试
            print(f"余额不足: {e.message}")
            print(f"错误码: {e.body.get('error', {}).get('code')}")
            raise

        except RateLimitError as e:
            # 429 — 使用 Retry-After 退避
            wait = e.retry_after or (2 ** attempt)
            print(f"限流中。{wait}s 后重试…")
            time.sleep(wait)

        except APIError as e:
            # 500 / 502 / 503 — 临时服务端错误
            if e.status_code in (500, 502, 503) and attempt < max_retries - 1:
                wait = 2 ** attempt
                print(f"服务端错误 {e.status_code}{wait}s 后重试…")
                time.sleep(wait)
            else:
                # 400 / 403 / 404 或重试耗尽
                code = e.body.get("error", {}).get("code", "unknown")
                print(f"API 错误 [{e.status_code}] {code}: {e.message}")
                raise

        except JarvisClawError as e:
            # x402 支付 / SDK 级错误
            print(f"SDK 错误: {e}")
            raise

    raise RuntimeError("超过最大重试次数")
go
package main

import (
	"context"
	"errors"
	"fmt"
	"time"

	jarvisclaw "github.com/api-jarvisclaw/go-sdk/v2"
)

func chatWithRetry(
	ctx context.Context,
	client *jarvisclaw.Client,
	messages []jarvisclaw.Message,
	maxRetries int,
) (*jarvisclaw.ChatResponse, error) {
	for attempt := range maxRetries {
		resp, err := client.ChatCompletion(ctx, "openai/gpt-4o-mini", messages)
		if err == nil {
			return resp, nil
		}

		var authErr *jarvisclaw.AuthenticationError
		if errors.As(err, &authErr) {
			// 401 — API Key 无效,不重试
			return nil, fmt.Errorf("认证失败: %w", err)
		}

		var balanceErr *jarvisclaw.InsufficientBalanceError
		if errors.As(err, &balanceErr) {
			// 402 — 充值 USDC 钱包
			return nil, fmt.Errorf("余额不足: %w", err)
		}

		var rateErr *jarvisclaw.RateLimitError
		if errors.As(err, &rateErr) {
			// 429 — 退避
			wait := time.Duration(1<<attempt) * time.Second
			fmt.Printf("限流中。%s 后重试...\n", wait)
			time.Sleep(wait)
			continue
		}

		var apiErr *jarvisclaw.APIError
		if errors.As(err, &apiErr) {
			switch apiErr.StatusCode {
			case 500, 502, 503:
				// 临时服务端错误 — 指数退避
				if attempt < maxRetries-1 {
					wait := time.Duration(1<<attempt) * time.Second
					fmt.Printf("服务端错误 %d%s 后重试...\n", apiErr.StatusCode, wait)
					time.Sleep(wait)
					continue
				}
			default:
				// 400 / 403 / 404 / upstream_error — 不可重试
				code := apiErr.Body["error"]
				return nil, fmt.Errorf("API 错误 [%d] %v: %s", apiErr.StatusCode, code, apiErr.Message)
			}
		}

		// PaymentError / 其他 SDK 错误
		return nil, fmt.Errorf("SDK 错误: %w", err)
	}
	return nil, fmt.Errorf("超过最大重试次数 (%d)", maxRetries)
}

错误类型没有 Type 字段

Go 的 APIError 暴露 StatusCodeMessageBody —— 请按具体错误类型或状态码分支, 而不是某个字符串判别字段。AuthenticationErrorRateLimitErrorInsufficientBalanceError 都嵌入 APIErrorPaymentError 嵌入 JarvisClawError。Python 侧层级一致 —— 详见 SDK → 错误处理