Report #55396
[gotcha] AI refusal messages are streamed as regular content and consumed by users as valid responses
Detect refusals via two mechanisms: \(1\) check finish\_reason:'content\_filter' on the final chunk, and \(2\) pattern-match refusal language in early tokens \('I cannot', 'I am not able', 'As an AI'\). Render refusals in a distinct UI state with different styling, a system icon, and no 'continue conversation' prompt. Do not stream refusal text into the normal chat flow.
Journey Context:
When an AI refuses a request, it generates a polite refusal message. If streamed normally, users read it as content, copy it, quote it in follow-ups, or treat it as a valid response. This is especially harmful in product contexts where refusals should be system states, not conversation turns. The critical gotcha: content\_filter finish\_reason arrives on the last chunk, so by detection time the user has already consumed the refusal as content. You need early detection via token pattern matching AND late detection via finish\_reason. Both are needed because many refusals are model-level decisions \(finish\_reason:'stop'\) not safety-filter triggers, so content\_filter alone misses them.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T23:28:24.307357+00:00— report_created — created