400 impreciso. Tres códigos de seguridad cubren los casos
que verás: un prompt o respuesta examinado, una llamada a herramienta denegada y una
llamada a herramienta retenida para aprobación humana.
Esta página es la referencia de esos códigos — el caso de uso de cada uno, el estado
HTTP exacto, lo que te cuesta y la única regla que más importa: la lógica de
reintento debe tratarlos como caso especial. Los tres están marcados como
skip-retry; reejecutar a ciegas la misma llamada simplemente vuelve a disparar el
mismo control.
Estos son códigos de aplicación — el gateway decidiendo no reenviar tu llamada.
Son distintos de los errores del proveedor upstream (un 429 del modelo, un desbordamiento
de contexto) y de los fallos de autenticación. Para saber por qué una solicitud
específica fue detenida, ve ¿Por qué se bloqueó esto?.
1. Los códigos de error de seguridad de llm de un vistazo
Cada bloqueo de seguridad devuelve HTTP 400 con un cuerpo de error con forma de OpenAI (error.code es la cadena tipada de abajo). En las rutas nativas de Claude
(/v1/messages) el mismo código viaja en la forma de error de Claude, así que el
enrutamiento del SDK es determinista entre protocolos.
| Código | Detiene | Coste de cuota |
|---|---|---|
guardrail_blocked | Un prompt o respuesta que golpeó una regla block | Ninguno |
firewall_blocked | Una llamada a herramienta / anuncio denegado | Sin tokens de modelo |
firewall_approval_pending | Una llamada a herramienta retenida para un revisor humano | Sin tokens de modelo |
2. guardrail_blocked — un prompt o respuesta examinado
Devuelto cuando una regla de guardrail con la acción block
se dispara — una palabra clave en lista de denegación, una coincidencia de regex, una
entidad de PII o secreto que elegiste bloquear en vez de enmascarar, un veredicto de
llm_judge o una verificación de grounding fallida.
HTTP 400. El mensaje nombra el guardrail y la regla que se disparó.
Impacto en la cuota: ninguno
Impacto en la cuota: ninguno
Una solicitud bloqueada no cuesta cuota. Un bloqueo en etapa de entrada se
dispara antes del medido, así que nunca se factura nada. Un bloqueo en etapa de
salida se ejecuta después de que el modelo responde, así que el gateway
reembolsa la cuota preconsumida antes de devolver el error. En cualquier caso
no pagas nada por una llamada bloqueada.
Por qué es skip-retry
Por qué es skip-retry
El veredicto es una propiedad del contenido, no del canal. Reejecutar el mismo
prompt — incluso contra un modelo diferente — produce el mismo bloqueo. Arregla la
entrada (o la política) en vez de reintentar.
Cómo se ve un mask en su lugar
Cómo se ve un mask en su lugar
Las reglas
mask no devuelven este código. Una coincidencia enmascarada (p. ej.
jane@acme.com → [EMAIL]) se redacta en su sitio y la llamada procede con
normalidad — obtienes un 200, solo que con el fragmento sensible eliminado. Solo
la acción block expone guardrail_blocked. (flag no cambia nada del tráfico en
absoluto.)3. firewall_blocked — una llamada a herramienta denegada
Devuelto cuando el firewall resuelve un veredicto deny para
una llamada a herramienta — un comando shell destructivo, un fetch con forma de SSRF, un
destino de egress en una lista de denegación, o una skill
en modo block.
Cómo se manifiesta el deny depende de la superficie de aplicación:
inbound / response / egress
HTTP 400 con
error.code = firewall_blocked. El cuerpo lleva error.metadata
estructurada (reason_code, factors de riesgo, risk_score) para que puedas
explicar el bloqueo, no solo verlo.superficie mcp
Devuelto como un error de herramienta (
firewall deny: <reason>), no un fallo de
transporte — así que el modelo ve el rechazo y puede elegir otra herramienta,
preguntar al usuario o detenerse, en vez de tumbar la ejecución.4. firewall_approval_pending — retenido para un humano
Devuelto en el instante en que una llamada a herramienta golpea un veredicto
pending_approval. Una compuerta human-in-the-loop no puede ser una espera en línea
bloqueante, así que el gateway devuelve una respuesta retenida de inmediato en vez de
hacer long-polling.
HTTP 400. El error lleva el id de aprobación para que tu agente sepa qué
retención resolver.
Este es el único código al que respondes resolviendo y reenviando — no tratándolo
como un fallo terminal:
Lee el id de aprobación del error retenido
El id es recuperable del cuerpo del error. No reintentes la llamada todavía — un
reintento ingenuo simplemente vuelve a retener.
Espera una decisión
Un revisor la resuelve desde la consola (Developer+), o tu sistema de aprobación
recibe un callback de webhook firmado con HMAC. Tu agente hace polling de
GET /api/v1/firewall/approvals/:id para el estado.Las rutas de aprobación (
/api/v1/firewall/approvals/*) se ejecutan sobre una clave
con alcance de gateway de firewall, no tu sesión de consola. Ve
Aprobación humana (HITL) para el bucle
completo y Payloads de webhook para la firma del
callback.5. Por qué los tres omiten el reintento
La lógica estándar de reintento del SDK asume que un400 podría tener éxito en un
segundo intento. Estos códigos rompen esa suposición — el bloqueo es determinista, así
que un reintento a ciegas desperdicia un viaje de ida y vuelta y (para las llamadas
retenidas) reencola silenciosamente una aprobación.
Qué significa 'skip-retry' en la práctica
Qué significa 'skip-retry' en la práctica
La propia maquinaria interna de reintento/fallback de OrcaRouter nunca reintenta una
llamada que devuelve uno de estos códigos contra otro canal. Refleja eso en tu
cliente: ante un código de seguridad, detente y actúa sobre el veredicto, no
hagas bucle.
La reacción correcta por código
La reacción correcta por código
guardrail_blocked→ arregla la entrada o relaja la política; expón el rechazo al usuario. No reintentes.firewall_blocked→ la acción está prohibida; haz que el agente elija una herramienta diferente o pida ayuda. No reintentes.firewall_approval_pending→ resuelve la retención, luego reenvía una vez con la cabecera de aprobación (§4). Un reintento sin la cabecera vuelve a retener.
6. Resumen de cuota y facturación
Un bloqueo de seguridad nunca te factura la unidad de trabajo bloqueada.| Código | Cuándo se dispara | Resultado de facturación |
|---|---|---|
guardrail_blocked (input) | Antes de la llamada al modelo | Nunca medido |
guardrail_blocked (output) | Después de que el modelo responde | Cuota preconsumida reembolsada |
firewall_blocked (inbound) | Antes de la llamada al modelo | Sin tokens de modelo |
firewall_approval_pending | Antes del despacho | Sin tokens de modelo |
7. Referencias relacionadas
¿Por qué se bloqueó esto?
Rastrea un único bloqueo hasta la regla, superficie y razón exactas que lo produjeron.
Glosario de veredictos
Cada veredicto del firewall — allow, audit, deny, sanitize, pending_approval,
cap_cost — y lo que emite cada uno.
Payloads de webhook y error
El sobre de error completo, los campos
error.metadata y la firma del callback de
aprobación.Modos de aplicación
Shadow, observe y enforce — cuándo un veredicto realmente cambia el tráfico.
