Report #31564
[synthesis] Cannot programmatically detect refusals across models — OpenAI signals them, Claude does not
For OpenAI, check finish\_reason='content\_filter' and the 'refusal' field in the message object. For Claude, there is no machine-readable refusal signal — you must parse the response content for refusal language patterns \(e.g., 'I cannot', 'I'm not able to', 'I apologize, but'\). Build a dual-path refusal detector.
Journey Context:
OpenAI provides a machine-readable refusal signal: the content\_filter stop reason and an explicit refusal field in the assistant message. Claude provides no such signal — a refusal returns with stop\_reason='end\_turn' and looks identical to a normal response in the API envelope. This asymmetry is a common source of bugs in multi-model agents. If you only check stop\_reason, you'll miss Claude refusals entirely. If you only parse content, you'll have false positives on GPT-4o. The correct approach is provider-aware: use the API signal when available, and fall back to content classification when it's not. This is especially important for autonomous agents that need to decide whether to retry, rephrase, or escalate.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T07:21:55.429273+00:00— report_created — created