Vai al contenuto principale
Quando un guardrail o il firewall ferma una richiesta, OrcaRouter restituisce un errore tipizzato su cui il tuo codice può fare branching — non un vago 400. Tre codici di sicurezza coprono i casi che incontrerai: un prompt o una risposta filtrati, una chiamata a tool negata e una chiamata a tool messa in attesa di approvazione umana. Questa pagina è il riferimento per quei codici — il caso d’uso di ciascuno, lo stato HTTP esatto, cosa ti costa, e l’unica regola che conta di più: la logica di retry deve trattarli come casi speciali. Tutti e tre sono marcati skip-retry; ri-eseguire ciecamente la stessa chiamata si limita a far scattare di nuovo lo stesso controllo.
Questi sono codici di applicazione — il gateway che decide di non inoltrare la tua chiamata. Sono distinti dagli errori del provider upstream (un 429 del modello, un overflow di contesto) e dai fallimenti di autenticazione. Per il motivo per cui una richiesta specifica è stata fermata, vedi Perché è stato bloccato?.

1. I codici di errore di sicurezza llm in sintesi

Ogni block di sicurezza restituisce HTTP 400 con un corpo di errore in forma OpenAI (error.code è la stringa tipizzata qui sotto). Sulle rotte native Claude (/v1/messages) lo stesso codice viaggia nella forma di errore Claude, quindi il routing dell’SDK è deterministico tra i protocolli.
CodiceFermaCosto in quota
guardrail_blockedUn prompt o una risposta che ha colpito una regola blockNessuno
firewall_blockedUna chiamata a tool / pubblicizzazione negataNessun token del modello
firewall_approval_pendingUna chiamata a tool in attesa di un revisore umanoNessun token del modello
Fai branching su error.code, mai sulla stringa del messaggio. I messaggi nominano lo specifico guardrail, regola o tool e cambieranno; i codici sono un contratto stabile.

2. guardrail_blocked — un prompt o una risposta filtrati

Restituito quando scatta una regola guardrail con l’azione block — una keyword in denylist, un hit di regex, un’entità PII o segreto che hai scelto di bloccare anziché mascherare, un verdetto llm_judge o un controllo di grounding fallito. HTTP 400. Il messaggio nomina il guardrail e la regola che è scattata.
Una richiesta bloccata non costa quota. Un block in fase di input scatta prima del metering, quindi non viene mai fatturato nulla. Un block in fase di output gira dopo che il modello ha risposto, quindi il gateway rimborsa la quota pre-consumata prima di restituire l’errore. In entrambi i casi non paghi nulla per una chiamata bloccata.
Il verdetto è una proprietà del contenuto, non del canale. Ri-eseguire lo stesso prompt — anche contro un modello diverso — produce lo stesso block. Correggi l’input (o la policy) invece di fare retry.
Le regole mask non restituiscono questo codice. Un match mascherato (es. jane@acme.com[EMAIL]) viene redatto in posto e la chiamata procede normalmente — ottieni un 200, solo con la porzione sensibile rimossa. Solo l’azione block fa emergere guardrail_blocked. (flag non cambia assolutamente nulla del traffico.)
{
  "error": {
    "type": "openai_error",
    "code": "guardrail_blocked",
    "message": "request blocked by guardrail \"pii-shield\": rule ssn (block)"
  }
}
Per i tipi di regola, le fasi e le azioni dietro questo codice, vedi Guardrails. Per l’envelope di errore campo per campo, vedi Payload di webhook ed errore.

3. firewall_blocked — una chiamata a tool negata

Restituito quando il firewall risolve un verdetto deny per una chiamata a tool — un comando shell distruttivo, un fetch in forma di SSRF, una destinazione di egress su una deny list o una skill in modalità block. Come emerge il deny dipende dalla superficie di applicazione:

inbound / response / egress

HTTP 400 con error.code = firewall_blocked. Il corpo porta error.metadata strutturati (reason_code, factors di rischio, risk_score) così puoi spiegare il block, non solo vederlo.

superficie mcp

Restituito come errore di tool (firewall deny: <reason>), non come fallimento di trasporto — così il modello vede il rifiuto e può scegliere un altro tool, chiedere all’utente o fermarsi, invece di andare in crash.
sanitize non è un block. Un verdetto sanitize redige le sottostringhe corrispondenti dagli argomenti della chiamata a tool e inoltra la chiamata ripulita — non restituisce mai firewall_blocked. (L’unica eccezione: sulla superficie inbound, dove non ci sono ancora argomenti al momento della chiamata, sanitize escala a un deny.)
{
  "error": {
    "type": "openai_error",
    "code": "firewall_blocked",
    "message": "tool \"shell.exec\" blocked by firewall: denied tool",
    "metadata": {
      "reason_code": "FW-TOOL-001",
      "risk_score": 92,
      "factors": ["denied_tool"]
    }
  }
}
In termini di quota, un block inbound scatta prima della chiamata al modello upstream, quindi non costa nessun token del modello. Vedi Glossario dei verdetti per ogni verdetto, e Chiamate a tool pericolose per le minacce da cui questo codice difende.

4. firewall_approval_pending — in attesa di un umano

Restituito nell’istante in cui una chiamata a tool colpisce un verdetto pending_approval. Un gate human-in-the-loop non può essere un’attesa inline bloccante, quindi il gateway restituisce subito una risposta held anziché fare long-polling. HTTP 400. L’errore porta l’id di approvazione così il tuo agent sa quale hold risolvere. Questo è l’unico codice a cui rispondi risolvendo e ri-inviando — non trattandolo come un fallimento terminale:
1

Leggi l'id di approvazione dall'errore held

L’id è recuperabile dal corpo dell’errore. Non fare ancora retry della chiamata — un retry ingenuo si limita a ri-trattenerla.
2

Attendi una decisione

Un revisore la risolve dalla console (Developer+), o il tuo sistema di approvazione riceve un callback webhook firmato con HMAC. Il tuo agent fa polling su GET /api/v1/firewall/approvals/:id per lo stato.
3

Ri-invia con il token di approvazione

Una volta approvata, ri-emetti la chiamata originale portando l’header monouso X-OrcaRouter-Firewall-Approval. Il gateway riconosce l’id e lascia passare quella sola chiamata.
Le rotte di approvazione (/api/v1/firewall/approvals/*) girano su una chiave con scope firewall-gateway, non sulla tua sessione di console. Vedi Approvazione umana (HITL) per il loop completo e Payload di webhook per la firma del callback.

5. Perché tutti e tre saltano il retry

La logica di retry standard degli SDK assume che un 400 possa avere successo a un secondo tentativo. Questi codici rompono quell’assunzione — il block è deterministico, quindi un retry cieco spreca un round trip e (per le chiamate held) ri-accoda silenziosamente un’approvazione.
Il meccanismo interno di retry/fallback di OrcaRouter non ri-tenta mai una chiamata che restituisce uno di questi codici contro un altro canale. Rispecchia ciò nel tuo client: su un codice di sicurezza, fermati e agisci sul verdetto, non ciclare.
  • guardrail_blocked → correggi l’input o allenta la policy; fai emergere il rifiuto all’utente. Non fare retry.
  • firewall_blocked → l’azione è vietata; fai scegliere all’agent un tool diverso o chiedere aiuto. Non fare retry.
  • firewall_approval_pending → risolvi l’hold, poi ri-invia una volta con l’header di approvazione (§4). Un retry senza l’header ri-trattiene.

6. Riepilogo quota e fatturazione

Un block di sicurezza non ti fattura mai l’unità di lavoro bloccata.
CodiceQuando scattaEsito di fatturazione
guardrail_blocked (input)Prima della chiamata al modelloMai conteggiato
guardrail_blocked (output)Dopo che il modello rispondeQuota pre-consumata rimborsata
firewall_blocked (inbound)Prima della chiamata al modelloNessun token del modello
firewall_approval_pendingPrima del dispatchNessun token del modello
Una regola llm_judge o grounding di un guardrail chiama effettivamente un modello per raggiungere il suo verdetto, e quei token del judge vengono fatturati come una sotto-voce judge separata — anche quando il verdetto è un block. È il costo del controllo, non della richiesta bloccata in sé.

7. Riferimenti correlati

Perché è stato bloccato?

Risali da un singolo block alla regola, superficie e motivazione esatte che lo hanno prodotto.

Glossario dei verdetti

Ogni verdetto del firewall — allow, audit, deny, sanitize, pending_approval, cap_cost — e cosa emette ciascuno.

Payload di webhook ed errore

L’envelope di errore completo, i campi error.metadata e la firma del callback di approvazione.

Modalità di applicazione

Shadow, observe ed enforce — quando un verdetto modifica davvero il traffico.
Per i controlli che producono questi codici, vedi Guardrails e Firewall; per il vocabolario, vedi il glossario dei concetti.