Errores
Los errores llegan con un código de estado HTTP y un cuerpo JSON en el formato del endpoint al que llamaste, así que tu SDK lanza sus excepciones habituales:
{ "error": { "message": "Your prepaid balance is used up. Add funds to continue sending requests." } }
El endpoint Messages usa la estructura de Anthropic, {"type": "error", "error": {"type": "...", "message": "..."}}. El message siempre indica qué salió mal y qué hacer al respecto.
Códigos de estado
| Estado | Causa | Qué hacer | ¿Reintentar? |
|---|---|---|---|
400 | La solicitud no es válida: falta model, JSON mal formado o una opción que el modelo no admite. | Corrige la solicitud. | No |
401 | La clave falta, está mal formada, se eliminó o se rotó. | Revisa la clave y el header. | No |
402 | Se agotó el saldo o el crédito del plan, o hay un pago del plan pendiente. | Agrega fondos o espera a que el plan se renueve; el mensaje indica cuál es el caso. | Tras corregirlo |
403 | El workspace de la clave no puede usar este modelo o endpoint; por ejemplo, una clave de plan que llama a un modelo que el plan no cubre. | Usa una clave de un workspace que sí tenga acceso. | No |
404 | El modelo no está disponible en este endpoint (el mensaje enumera los modelos que sí lo están), la ruta no existe o el recurso pertenece a otro proyecto. | Revisa el ID del modelo y el endpoint. | No |
405 | El método no es compatible con esta ruta. | Usa el método indicado en el header Allow. | No |
409 | Se reutilizó una clave de idempotencia o un recurso aún no está listo. | Usa una clave nueva para cada solicitud nueva; espera a que el recurso esté listo. | A veces |
413 | El cuerpo de la solicitud supera los 64 MiB. | Envía una URL en lugar de datos inline o divide la entrada. | No |
415 | El cuerpo no es JSON ni multipart form data. | Configura Content-Type. | No |
429 | Demasiadas solicitudes, o demasiadas en curso al mismo tiempo. | Espera lo que indique Retry-After. | Sí |
500, 502 | El modelo no pudo completar la solicitud. | Reintenta con backoff. | Sí |
503 | Un problema temporal, incluso cuando no se pudo verificar tu clave o tu saldo. No se envió ni se cobró nada. | Reintenta en unos momentos. | Sí |
Las solicitudes rechazadas antes de que se ejecutara un modelo —todos los 4xx anteriores y los 503— no se cobran.
Reintentos
Reintenta los 429, 500, 502 y 503 con backoff exponencial y jitter, y respeta Retry-After cuando esté presente:
async function withRetries(call, attempts = 5) {
for (let attempt = 0; ; attempt++) {
try {
return await call();
} catch (error) {
const status = error.status;
const retryable = status === 429 || status >= 500;
if (!retryable || attempt + 1 >= attempts) throw error;
const retryAfter = Number(error.headers?.["retry-after"]);
const delay = Number.isFinite(retryAfter) && retryAfter > 0
? retryAfter * 1000
: Math.min(30_000, 500 * 2 ** attempt) * (0.5 + Math.random());
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
Los SDK de OpenAI y Anthropic ya reintentan estos códigos de estado un par de veces; para trabajos por lotes, aumenta maxRetries en lugar de envolverlos con otra capa de reintentos.
Agrega un Idempotency-Key a las solicitudes que reintentes, para que un reintento tras un error de red nunca se procese dos veces.
Errores en un stream
Una vez que un stream comenzó, los errores llegan como un evento dentro del stream, no como un código de estado HTTP. Consulta streaming.
Errores del modelo
Cuando el propio modelo no puede completar una solicitud, el mensaje es uno neutral: "The model could not complete this request. Please try again." Reintenta o, si sigue ocurriendo, prueba con otro modelo.