Stop generation button is present during streaming
Why it matters
A streaming AI response can run 10–30 seconds. Without a stop control wired to AbortController, users who trigger an unwanted response — wrong prompt, sensitive topic, runaway context — have no recourse except a full page reload, which destroys conversation history. This directly violates iso-25010:2011 reliability.fault-tolerance: the system must handle user-initiated cancellation gracefully. Beyond UX, holding an open streaming connection for a generation the user abandoned wastes API credits and server resources. On metered plans this creates real cost exposure.
Severity rationale
Critical because the user has no escape from an unwanted or runaway generation except destroying the page — a hard blocker for any conversational AI product.
Remediation
Wire useChat's stop() or an AbortController to a button that renders only while isLoading is true. The control must be in the DOM and visible during streaming — dead code in JSX does not satisfy this check.
const { stop, isLoading } = useChat()
<button
onClick={stop}
aria-label="Stop generating"
className={isLoading ? 'flex items-center gap-1' : 'hidden'}
>
<SquareIcon className="w-4 h-4" /> Stop
</button>
For raw fetch implementations, store an AbortController in a ref and call .abort() from the stop handler in src/components/chat/ChatInput.tsx.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the AI UX Patterns Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- iso-25010:2011 · reliability.fault-tolerance — Fault Tolerance — ability to operate as intended despite faults (stream cancellation as a reliability control)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ai-ux-patterns·automated