Al conectar Roo Code a una API de terceros, la mayoría de los errores no se deben a la capacidad del modelo, sino a la elección del proveedor, la Base URL, la clave, el límite de peticiones o la red: un 401 apenas terminas de configurar, un 404 al cambiar de dirección, un 429 a mitad de una tarea larga, un streaming que se queda colgado hasta el timeout. El orden de trabajo es mirar primero el código de estado y el tipo de error, después el request-id y solo al final el prompt. Este artículo separa 401, 404, 429, límite de contexto y timeouts, y ofrece pasos de diagnóstico, una lista de registro y código de ejemplo. Modelos y facturación se rigen por precios de modelos.

1. Primero por capas: dónde ocurre el error

Una petición atraviesa el cliente de Roo Code, el host de extensiones de VS Code, la red y el proxy, el gateway y el modelo upstream. Un mismo 401 puede ser una clave incorrecta o un proveedor incompatible; un mismo 404 puede ser una ruta con /v1 de más o un ID de modelo inexistente. Trabaja por capas para no cambiar la configuración en la dirección equivocada.

Código Tipo de error Causa habitual Qué hacer
400 invalid_request_error Parámetros, longitud de contexto o límite de gasto Cambia la petición o ajusta el límite y reintenta
401 authentication_error Clave ausente, incorrecta, caducada o cabecera de autenticación incompatible Corrige la credencial; no reintentes
402 billing_error Problema de facturación o saldo Revisa la facturación
403 permission_error La clave no tiene permiso de modelo o de proyecto Revisa la autorización
404 not_found_error Ruta o ID de modelo incorrectos Revisa Base URL y nombre del modelo
413 request_too_large El cuerpo supera el límite de la interfaz Comprime o divide la petición
429 rate_limit_error Frecuencia, concurrencia o límite de gasto Espera y reintenta
500 api_error Error interno del servidor Reintenta con espera
504 timeout_error Tiempo de procesamiento agotado Cambia a streaming o divide en lotes

Conserva el request-id de las cabeceras o del cuerpo del error. Registra al menos hora, código de estado, tipo de error, ID de modelo e ID de petición; no registres la clave completa ni código sensible.

2. 401: proveedor, clave y cabecera de autenticación

En Roo Code, el desplegable de proveedor y el campo de clave están separados; el 401 más común no es una clave inválida, sino una combinación incorrecta: una clave compatible con OpenAI en el proveedor Anthropic, o al revés; una Base URL del entorno A con una clave del entorno B; un perfil de API que conserva la clave anterior después de cambiar.

Otras causas habituales: espacios, saltos de línea, comillas o caracteres de ancho completo alrededor de la clave; una clave eliminada, caducada o perteneciente a otro espacio de trabajo; un proxy corporativo que reescribe o elimina la cabecera Authorization; una configuración simultánea de inicio de sesión por suscripción y clave de API en la misma extensión.

Orden de diagnóstico:

  1. Confirma que el tipo de proveedor coincide con el protocolo de la Base URL: OpenAI compatible usa /v1/chat/completions; Anthropic usa /v1/messages.
  2. Haz una petición mínima directa desde la terminal con la misma clave y la misma Base URL.
  3. Si la petición directa funciona y Roo Code falla, el problema está en la configuración del proveedor, el perfil o el proxy; si la directa también falla, está en la clave, el gateway o la red.
  4. Prueba con una clave nueva para descartar un error de copiado.

El 401 no se reintenta; reintentar solo amplifica los registros y las alertas.

3. 404: ruta de la Base URL e ID de modelo

Hay dos clases de 404: la ruta no existe o el modelo no existe.

Problema de ruta: en el proveedor compatible con OpenAI, la Base URL suele escribirse hasta /v1, y el cliente añade /chat/completions. Si escribes la ruta completa /v1/chat/completions, la ruta final puede duplicarse. Una barra final, una barra doble, mayúsculas o espacios de más también producen 404. El proveedor Anthropic añade /v1/messages; si le das una dirección compatible con OpenAI, también devolverá 404.

Problema de modelo: cuando el mensaje incluye model not found, invalid model o The model does not exist, copia el ID exacto de la lista de modelos del gateway o de la página de precios. Los alias, los sufijos de fecha y las mayúsculas pueden variar; algunos gateways exigen un prefijo de proveedor. Confirma también que la clave tenga permiso para ese modelo; la falta de permiso a veces devuelve 403 y a veces 404.

Comprobación rápida: llama a /v1/models para ver los modelos visibles con la clave actual y envía una petición mínima con un ID de esa lista.

4. 429: límites, cuota y tormenta de reintentos

El 429 indica que la petición superó un límite de velocidad, concurrencia o gasto. Causas frecuentes:

  • Se superó el número de peticiones o de tokens por minuto.
  • Varias herramientas o varios compañeros comparten una misma clave.
  • Las subtareas del Orchestrator o las llamadas paralelas a herramientas elevan la concurrencia instantánea.
  • Los reintentos no aplican espera y forman una tormenta.
  • Se alcanzó el saldo de la cuenta o el límite de gasto del espacio de trabajo.

Revisa primero la cabecera retry-after: si existe, espera lo que indica; si no, aplica espera exponencial con jitter aleatorio y fija un máximo de intentos. Algunos 429 por cuota no incluyen retry-after; esperar no los resuelve, porque hace falta recargar o ajustar el límite.

Cuidado con la superposición de reintentos: Roo Code puede reintentar por su cuenta, el SDK o el gateway también pueden hacerlo y la capa de negocio añade otro nivel; el número real de peticiones se multiplica. Planifica juntos los reintentos del cliente, del SDK y de la aplicación. No reintentes 401, 403, 404 ni 400.

5. 400 y 413: longitud de contexto y cuerpo de la petición

El exceso de contexto suele devolver 400, con mensajes como context length, maximum context o prompt is too long. La causa no es que el modelo esté roto, sino que el presupuesto de entrada más salida supera la ventana.

En Roo Code hay que vigilar la ventana de contexto configurada: si escribes un valor mayor que el que soporta el modelo, el cliente recortará según un presupuesto incorrecto o enviará una petición demasiado larga, y el resultado será un 400. Ajusta la ventana al valor de la documentación del modelo y activa la compresión de contexto o condensing si la versión actual lo permite.

Orden de tratamiento:

  1. Reduce el número de archivos leídos de una vez y entrega solo los fragmentos relevantes.
  2. Comprime la salida de terminal y de las herramientas MCP y conserva solo los campos necesarios.
  3. Divide los documentos largos por capítulos y procésalos por partes antes de resumir.
  4. Limpia las conversaciones antiguas y conserva el sistema, las últimas vueltas y un resumen.
  5. Deja espacio para la salida; max_tokens solo limita la salida y no resuelve un exceso de entrada.

El 413 request_too_large indica un cuerpo de petición demasiado grande y no es lo mismo que la longitud de contexto. Lo provocan sobre todo capturas de pantalla, PDF e imágenes en base64; comprime las imágenes, reduce los adjuntos o divide la petición.

6. Timeouts y cortes de flujo: streaming, proxy y tareas largas

Roo Code usa salida en streaming por defecto. Una petición en streaming puede devolver primero HTTP 200 y enviar después un evento de error dentro del flujo SSE; si el cliente solo mira el código de estado, tomará el fallo por éxito. Hay que analizar los eventos de error del flujo y confirmar que llegó la marca de finalización normal; de lo contrario, marca el resultado como incompleto.

Fuentes habituales de timeout:

  • Proxies corporativos, VPN o inspección TLS que inestabilizan la conexión.
  • Problemas de DNS, IPv6, firewall o MTU.
  • Peticiones demasiado largas y conexiones inactivas que se cierran.
  • Tareas largas del agente que ejecutan herramientas sin parar y superan el límite del cliente o del gateway.
  • Colas en el modelo upstream y un primer byte muy lento.

En la práctica, prioriza el streaming; configura un timeout razonable por petición; divide las tareas largas en etapas; reduce el alcance de las herramientas con aprobación automática; cambia de red o usa un hotspot móvil para saber si el problema es local. La inspección TLS corporativa exige que VS Code y el sistema confíen en la CA correspondiente; los clientes basados en Node a veces necesitan NODE_EXTRA_CA_CERTS.

7. Registros y soporte: cómo explicar el problema

No envíes solo «da error». Recoge la información con esta lista:

  1. Hora del incidente, zona horaria y duración.
  2. Versión de Roo Code, versión de VS Code y sistema operativo.
  3. Tipo de proveedor, Base URL (solo el dominio) e ID de modelo.
  4. Si usaba streaming, duración de la petición y número de reintentos.
  5. Código HTTP, tipo de error y mensaje completo.
  6. request-id, que puede estar en la cabecera y en el cuerpo.
  7. Alcance: un equipo, un proyecto, una red o todo el equipo de trabajo.
  8. Reproducción mínima: un curl o un repositorio mínimo, y el resultado de la misma petición contra el punto de entrada oficial.

Ubicación de los registros: en el panel Output de VS Code busca el canal de Roo Code; los errores del host de extensiones y de las herramientas MCP pueden estar en la consola de Developer Tools; si el problema es del gateway, envía el request-id al soporte del gateway. Tras el archivo del repositorio principal, los issues de GitHub pueden ser de solo lectura; confirma primero el canal de soporte de la bifurcación que uses. Anonimiza los registros de forma concreta: deja solo los cuatro primeros y los cuatro últimos caracteres de la clave, y trata prompts y código según las normas de la empresa.

8. Ejemplo: decidir si reintentar según el tipo de error

La siguiente demostración usa la interfaz compatible con OpenAI: 401 y 404 fallan de inmediato; 429, 5xx y timeout se reintentan con espera. Sirve como script independiente para reproducir el problema y también puede incorporarse a tus tareas por lotes.

import os
import random
import time

from openai import (
    APIConnectionError,
    APIStatusError,
    APITimeoutError,
    AuthenticationError,
    NotFoundError,
    OpenAI,
    RateLimitError,
)

client = OpenAI(
    base_url=os.environ["OPENAI_BASE_URL"],
    api_key=os.environ["OPENAI_API_KEY"],
)

def ask(prompt: str, retries: int = 4) -> str:
    for attempt in range(retries):
        try:
            resp = client.chat.completions.create(
                model=os.environ["OPENAI_MODEL"],
                messages=[{"role": "user", "content": prompt}],
                timeout=120,
            )
            return resp.choices[0].message.content or ""
        except AuthenticationError as exc:
            raise SystemExit(f"401: revisa proveedor, clave y cabecera; request-id={exc.request_id}") from exc
        except NotFoundError as exc:
            raise SystemExit(f"404: revisa Base URL e ID de modelo; request-id={exc.request_id}") from exc
        except RateLimitError:
            wait = min(2 ** attempt, 20) + random.random()
            print(f"429: reintento en {wait:.1f}s")
            time.sleep(wait)
        except (APITimeoutError, APIConnectionError):
            wait = min(2 ** attempt, 10) + random.random()
            print(f"Timeout o fallo de conexión: reintento en {wait:.1f}s")
            time.sleep(wait)
        except APIStatusError as exc:
            if exc.status_code >= 500:
                wait = min(2 ** attempt, 20) + random.random()
                print(f"{exc.status_code}: reintento en {wait:.1f}s")
                time.sleep(wait)
                continue
            raise

    raise RuntimeError("Se agotaron los reintentos; pasa a degradación o alerta")

print(ask("Responde solo OK"))

El ejemplo no configura explícitamente el número de reintentos del SDK; en producción hay que coordinar los reintentos predeterminados del SDK con los de la aplicación. La Base URL suele ser https://ai.zhongshangqihang.com/v1, y el ID de modelo se copia de precios de modelos.

Preguntas frecuentes

¿Un 401 siempre significa que la clave está mal?

No. Un tipo de proveedor incompatible, una Base URL que apunta a otro entorno o un proxy que reescribe la cabecera de autenticación también devuelven 401. Prueba primero con la misma clave y la misma Base URL de forma directa, y revisa después el proveedor y el perfil de configuración de Roo Code.

El 404 dice model not found, ¿cómo confirmo el ID?

Llama a /v1/models para obtener la lista visible con la clave actual, copia el ID exacto y no lo escribas de memoria. Confirma también si la Base URL duplica la ruta y si el protocolo del proveedor coincide.

¿Un 429 se recupera siempre esperando un poco?

No necesariamente. Los límites de velocidad suelen recuperarse; los 429 por cuota o saldo pueden no incluir retry-after, y esperar no sirve: hay que ajustar el límite o recargar. Revisa el tipo de error y las cabeceras antes de decidir.

¿El exceso de contexto es un problema del modelo?

Normalmente no. Es el presupuesto de entrada más salida superando la ventana, o una ventana configurada en Roo Code mayor que la real del modelo. Reducir la entrada, activar la compresión y dividir la tarea suele ser más directo que cambiar de modelo.

Si el streaming devuelve 200 y luego se corta, ¿cuenta como éxito?

No. Una respuesta en streaming puede enviar un evento de error por SSE después del 200. El cliente debe analizar el flujo y confirmar la finalización normal; de lo contrario, debe marcarlo como incompleto y reintentar o alertar.

Siguiente paso

Crea primero una clave de prueba en ZSQH AI Gateway, ensaya con el curl y el script anteriores los casos 401, 404, 429 y timeout, y conecta después el monitoreo de producción. La disponibilidad y la facturación de los modelos se rigen por precios de modelos.

Lecturas relacionadas:

Nota: Roo Code, Cline, Cursor, Claude Code, Anthropic y OpenAI son marcas o marcas registradas de sus respectivos titulares. Este artículo solo ofrece una explicación técnica de diagnóstico y no implica afiliación ni relación de colaboración con esas empresas. Los tipos de error y el comportamiento del cliente pueden cambiar según la versión; consulta la documentación oficial y los anuncios del repositorio.