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"继续轮询直到 completed 或 failed

代码示例 ​

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 暴露 StatusCode、Message 和 Body —— 请按具体错误类型或状态码分支, 而不是某个字符串判别字段。AuthenticationError、RateLimitError、InsufficientBalanceError 都嵌入 APIError;PaymentError 嵌入 JarvisClawError。Python 侧层级一致 —— 详见 SDK → 错误处理。