[BUG] Reply text starting with "You've used" is rendered as a rate-limit notice

Status Open
Reported on v2.1.288
Maintainer reply None cached
Activity 0 comments · opened Oct 3, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Any assistant reply whose text begins with "You've used" is drawn by the rate-limit notice row instead of the normal reply renderer. The same happens for the other usage-limit prefixes the renderer checks ("You've hit your", "You've reached your", "You're close to", "You're out of usage credits", "Now using usage credits", and the "Fable … requires usage credits." pattern).

Visible symptoms, all at once:

  • no ⏺ speaker marker, so the reply visually merges into the thinking block above it
  • text painted in the error color
  • markdown left unrendered (literal ** around bold text)
  • a spurious "/usage-credits to finish what you're working on." hint appended under the reply

Usage was nowhere near a limit when this happened: /usage showed 4% session, 42% weekly, 55% Fable weekly, all severity normal, and the oauth usage endpoint reported no warning state.

What Should Happen?

A reply that merely starts with those words should render like any other reply: ⏺ marker, normal color, markdown rendered, no usage hint. Only messages that actually come from the rate-limit path should use the rate-limit row.

Error Messages/Logs

Steps to Reproduce

  1. Start Claude Code 2.1.288 signed in with a claude.ai subscription (seen on Max 20x).
  2. Send: Begin your reply with the exact words "You've used" and then say anything.
  3. Observe the reply: no ⏺ marker, error-colored text, literal ** markdown, and "/usage-credits to finish what you're working on." appended.
  4. Send the same request asking for a reply that starts with any other words: renders normally.

Cause as far as I can see in the bundle: the reply text renderer (the function taking {param, addMargin, shouldShowDot, verbose, isApiError, apiErrorKind, onOpenRateLimitOptions, onRateLimitAutoQueueContinue}) runs the text through a predicate that is prefixList.some(p => text.startsWith(p)) || regexList.some(r => r.test(text)) and, on a hit, mounts the rate-limit row component with the reply text. There is no check that the message originated from the rate-limit machinery, so ordinary model output that happens to open with one of those phrases is misclassified. The predicate and prefix list are present in every build I have from 2.1.280 through 2.1.288.

Claude Model

_No response_

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.288 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Model: Fable 5.1. Terminal: Ghostty. macOS 27.2.

View original on GitHub ↗