Repository navigation
Description
Preflight Checklist
- I have searched existing issues and this hasn't been reported yet
- This is a single bug report (please file separate reports for different bugs)
- I am using the latest version of Claude Code
What's Wrong?
After hours of inactivity in a long-running session, every new message from the user immediately returns "API Error: Rate limit reached" without making any API call. The error is generated client-side by Claude Code, not by the Anthropic API. The user cannot proceed with any work — every message, including simple ones like "proceed", triggers the same error.
What Should Happen?
After hours of inactivity, the rate limit budget should have fully reset. A simple message should be sent to the API and receive a normal response.
Error Messages/Logs
Session log: `~/.claude/projects/-home-rich-RE6D/7137463d-be5d-4d5e-a97d-bb12b5e44b58.jsonl`
**Six consecutive blocked requests between 13:11:09 and 13:11:28 UTC on 2026-03-29:**
Each error entry has this structure:
{
"type": "assistant",
"message": {
"model": "<synthetic>",
"role": "assistant",
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
},
"content": [
{
"type": "text",
"text": "API Error: Rate limit reached"
}
]
},
"error": "rate_limit",
"isApiErrorMessage": true
}
Key observations:
| Field | Value | Significance |
|-------|-------|-------------|
| `model` | `"<synthetic>"` | NOT a real API response — generated by Claude Code client |
| `input_tokens` | `0` | No tokens were sent to the API |
| `output_tokens` | `0` | No tokens were received from the API |
| `cache_read_input_tokens` | `0` | No cache was accessed |
| `isApiErrorMessage` | `true` | Claude Code flagged this as an API error |
| `error` | `"rate_limit"` | Client-side classification |
**Contrast with the first successful request after the user persisted (13:11:37 UTC):**
{
"model": "claude-opus-4-6",
"usage": {
"input_tokens": 3,
"cache_creation_input_tokens": 1315,
"cache_read_input_tokens": 668864,
"output_tokens": 1,
"service_tier": "standard"
}
}Steps to Reproduce
- Run a Claude Code session for multiple days with heavy agent usage (many subagent dispatches, large code changes)
- Accumulate a conversation transcript of ~74MB (the
.jsonlfile grows as the session continues) - Leave the session idle for several hours
- Send any message (e.g., "proceed")
- Observe: immediate
"API Error: Rate limit reached"with no actual API call
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
No response
Claude Code Version
2.1.81
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
Xterm
Additional Information
Bug Report: Client-side rate limiter blocks requests with zero API calls when conversation transcript is large
Title
Client-side rate limiter blocks requests with zero API calls when conversation transcript is large (~74MB) — false rate_limit error with synthetic model and 0 input/output tokens
Environment
- Claude Code Version: 2.1.81
- OS: Ubuntu Linux 6.17.0-19-generic
- Shell: bash
- Model: claude-opus-4-6 (1M context)
- Platform: CLI (
entrypoint: "cli") - Session ID: 7137463d-be5d-4d5e-a97d-bb12b5e44b58
Description
After hours of inactivity in a long-running session, every new message from the user immediately returns "API Error: Rate limit reached" without making any API call. The error is generated client-side by Claude Code, not by the Anthropic API. The user cannot proceed with any work — every message, including simple ones like "proceed", triggers the same error.
Steps to Reproduce
- Run a Claude Code session for multiple days with heavy agent usage (many subagent dispatches, large code changes)
- Accumulate a conversation transcript of ~74MB (the
.jsonlfile grows as the session continues) - Leave the session idle for several hours
- Send any message (e.g., "proceed")
- Observe: immediate
"API Error: Rate limit reached"with no actual API call
Expected Behavior
After hours of inactivity, the rate limit budget should have fully reset. A simple message should be sent to the API and receive a normal response.
Actual Behavior
Claude Code's client-side rate limiter blocks the request before it reaches the Anthropic API. The user sees "API Error: Rate limit reached" and cannot use the tool at all.
Evidence from Logs
Session log: ~/.claude/projects/-home-rich-RE6D/7137463d-be5d-4d5e-a97d-bb12b5e44b58.jsonl
Six consecutive blocked requests between 13:11:09 and 13:11:28 UTC on 2026-03-29:
Each error entry has this structure:
{
"type": "assistant",
"message": {
"model": "<synthetic>",
"role": "assistant",
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
},
"content": [
{
"type": "text",
"text": "API Error: Rate limit reached"
}
]
},
"error": "rate_limit",
"isApiErrorMessage": true
}Key observations:
| Field | Value | Significance |
|---|---|---|
model |
"<synthetic>" |
NOT a real API response — generated by Claude Code client |
input_tokens |
0 |
No tokens were sent to the API |
output_tokens |
0 |
No tokens were received from the API |
cache_read_input_tokens |
0 |
No cache was accessed |
isApiErrorMessage |
true |
Claude Code flagged this as an API error |
error |
"rate_limit" |
Client-side classification |
Contrast with the first successful request after the user persisted (13:11:37 UTC):
{
"model": "claude-opus-4-6",
"usage": {
"input_tokens": 3,
"cache_creation_input_tokens": 1315,
"cache_read_input_tokens": 668864,
"output_tokens": 1,
"service_tier": "standard"
}
}This successful request shows cache_read_input_tokens: 668,864 — the session context is approximately 668K tokens. This is likely what the client-side rate limiter is counting against the budget.
Root Cause Hypothesis
The client-side rate limiter appears to calculate the token cost of the next request by estimating the context size (668K+ tokens) and checking it against a per-minute or per-hour token budget. For very large sessions, the CONTEXT ALONE may exceed the rate limit budget — even though the user's actual message is just a few tokens.
This creates a situation where:
- The session grows over days of heavy use
- The context window fills with conversation history
- Eventually the context size exceeds the rate limit's per-window token budget
- Every subsequent request is blocked client-side, regardless of actual API availability
- The user is permanently locked out until they start a new session
Session Size Data
| Metric | Value |
|---|---|
| Session transcript file | 74,019,933 bytes (74MB) |
| Estimated context tokens | 668,864 (from cache_read_input_tokens) |
| Session duration | ~4 days (2026-03-25 to 2026-03-29) |
| Subagents dispatched | 50+ over the session |
| Session compactions | Multiple (context was compressed during the session) |
Impact
- Severity: High — user is completely blocked from using Claude Code
- Workaround: Start a new session (loses all conversation context)
- User experience: Extremely frustrating — the error message gives no indication that the session size is the problem, and retrying makes it worse (each retry attempt may count against the budget)
Suggested Fix
- Don't count cached/context tokens against the rate limit budget — the user isn't "using" more tokens by having a long session. The cache is already paid for.
- If rate limiting must include context, reset the budget after idle periods — hours of inactivity should fully reset any per-minute/per-hour budget.
- Show a more helpful error message — instead of "API Error: Rate limit reached", show "Session context is very large (668K tokens). Consider starting a new session with
/compactor a fresh session." - Distinguish client-side rate limiting from API rate limiting — the current message is identical for both, making it impossible for the user to diagnose.
Activity
github-actions commentedon Mar 29, 2026
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
rwp65 commentedon Mar 29, 2026
updated information:
Bug Report: Client-side rate limiter blocks requests with zero API calls — false rate_limit error
Title
Client-side rate limiter generates false
rate_limiterrors withmodel: "<synthetic>"andinput_tokens: 0— no API call made. Triggered by BOTH large transcripts AND concurrent subagent spawns.Environment
entrypoint: "cli")Description
After hours of inactivity in a long-running session, every new message from the user immediately returns
"API Error: Rate limit reached"without making any API call. The error is generated client-side by Claude Code, not by the Anthropic API. The user cannot proceed with any work — every message, including simple ones like "proceed", triggers the same error.Steps to Reproduce
.jsonlfile grows as the session continues)"API Error: Rate limit reached"with no actual API callExpected Behavior
After hours of inactivity, the rate limit budget should have fully reset. A simple message should be sent to the API and receive a normal response.
Actual Behavior
Claude Code's client-side rate limiter blocks the request before it reaches the Anthropic API. The user sees
"API Error: Rate limit reached"and cannot use the tool at all.Evidence from Logs
Session log:
~/.claude/projects/-home-rich-RE6D/7137463d-be5d-4d5e-a97d-bb12b5e44b58.jsonlSix consecutive blocked requests between 13:11:09 and 13:11:28 UTC on 2026-03-29:
Each error entry has this structure:
{ "type": "assistant", "message": { "model": "<synthetic>", "role": "assistant", "usage": { "input_tokens": 0, "output_tokens": 0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0 }, "content": [ { "type": "text", "text": "API Error: Rate limit reached" } ] }, "error": "rate_limit", "isApiErrorMessage": true }Key observations:
model"<synthetic>"input_tokens0output_tokens0cache_read_input_tokens0isApiErrorMessagetrueerror"rate_limit"Contrast with the first successful request after the user persisted (13:11:37 UTC):
{ "model": "claude-opus-4-6", "usage": { "input_tokens": 3, "cache_creation_input_tokens": 1315, "cache_read_input_tokens": 668864, "output_tokens": 1, "service_tier": "standard" } }This successful request shows
cache_read_input_tokens: 668,864— the session context is approximately 668K tokens. This is likely what the client-side rate limiter is counting against the budget.Root Cause Hypothesis
The client-side rate limiter appears to calculate the token cost of the next request by estimating the context size (668K+ tokens) and checking it against a per-minute or per-hour token budget. For very large sessions, the CONTEXT ALONE may exceed the rate limit budget — even though the user's actual message is just a few tokens.
This creates a situation where:
Session Size Data
Impact
Second Occurrence — Concurrent Subagent Trigger (Same Session Day, Different Session)
Session ID: 13d72e07-75c2-49af-9463-6cd2b57528a7
Timestamp: 2026-03-29T21:15:06.774Z
What Happened
User dispatched 3 Opus subagents in parallel using the Agent tool. All 3 returned
"API Error: Rate limit reached"immediately. The main session was working normally — the rate limit only hit the subagent spawns.Evidence from Logs
Same signature as Occurrence 1:
{ "model": "<synthetic>", "input_tokens": 0, "output_tokens": 0, "timestamp": "2026-03-29T21:15:06.774Z" }Session Size Data — MUCH SMALLER Than Occurrence 1
Critical Finding
This is NOT a transcript size issue. The session was 2.9 MB (vs 74 MB) — 25x smaller. The trigger was spawning 3 subagents simultaneously. Each subagent inherits the parent conversation context and makes its own API call. The client-side rate limiter appears to calculate:
If this exceeds the per-minute token budget, all 3 are blocked — even though each individual request would be fine.
Additional Context
Updated Root Cause Hypothesis
The client-side rate limiter multiplies estimated context tokens by the number of concurrent requests. For a session with ~400K context tokens:
This creates a progressive degradation: as the session grows, fewer concurrent agents can be spawned before hitting the false limit. Eventually even a single request may be blocked (Occurrence 1).
Suggested Fix
cache_read_input_tokens.estimated_tokens,budget_remaining,concurrent_requestsin the log entry so users can understand WHY they were blocked.marlvinvu commentedon Apr 2, 2026
My Claude says your finding — both occurrences — may be the root cause for dozens of unexplained rate limit issues: #38239, #37917, #39465, #39938, #40079, #40085, #40128, #40273, #40438, #40504, #40532. The evidence of model: "" with input_tokens: 0 is the smoking gun — proving the request was NEVER sent to the API. And your second finding is even more important: the rate limiter multiplies context × concurrent requests — explaining why multi-agent workflows get blocked even though each individual request is within budget. I've commented on those issues linking to yours so they know. Thank you for analyzing the logs this thoroughly — this is forensic work that Anthropic should read carefully.
ArkNill commentedon Apr 3, 2026
Adding independent confirmation from a different setup.
I scanned all session JSONL files on my machine (Max 20, v2.1.90-91, Linux) for
<synthetic>model entries:<synthetic>entries across 65 session filesacompactsub-agents (compaction processes hitting the false rate limiter)Example entry from our logs:
{"model": "<synthetic>", "usage": {"input_tokens": 0, "output_tokens": 0}, "stop_reason": "stop_sequence"}This isn't a rare edge case — it's happening routinely. The
acompactsub-agent hits are particularly concerning because they mean the compaction process itself gets blocked by the client-side rate limiter, potentially leaving sessions in a degraded state.Tested on v2.1.91: no fix mentioned in changelog, and the underlying rate limiter logic (
context_size × concurrent_requests) hasn't changed.@rwp65 Your original analysis was spot-on. This is one of several unfixed bugs we've been tracking across the rate limit issues — documented at claude-code-cache-analysis as Bug 3 in the 6-layer model.
dancinlife commentedon Apr 3, 2026
How we identified and mitigated rate limit bugs — full operational report
@dliedke This bug (false rate limiter) is confirmed still present in v2.1.91. Here's what we've built to work around the full set of rate limit issues, including this one.
Our monitoring setup
We run 9 MAX accounts with a custom launcher (
ccmon) that tracks real-time usage via the OAuth usage API. This is what our dashboard looks like:What we discovered through multi-account monitoring
By watching utilization patterns across 9 accounts simultaneously, we identified contamination vectors that silently link accounts:
claude logindoesn't clearoauthAccountin.claude.json— the previous account'saccountUuidpersists into the new config. This causes:groveConfigCache,passesEligibilityCache,overageCreditGrantCachepile up foreign UUIDsContamination vectors we've mapped
claude loginnot clearingoauthAccountoauthAccount+ 3 cache fields before login.claude.jsonacross config dirssettings.jsonis safeprojects/directorymemory/symlinks only~/.claude-env-{PID}).zshrc<synthetic>entries)Remaining bugs after v2.1.91 cache fix
The cache regression fix was significant — 95-99% cache read restored. But 4 bugs still cause unexpected consumption:
<synthetic>entries across 65 sessionsmaxResultSizeCharsfix is MCP-only, built-in tools unaffectedFull measured data: claude-code-cache-analysis
junaidtitan commentedon Apr 3, 2026
A 74MB transcript triggering the client-side rate limiter is a session size problem. Cozempic v1.4.1 can dramatically shrink these files — the aggressive prescription runs 17 strategies that target every bloat type.
For a session that size:
cozempic treat <session> -rx aggressive --executeOr install the guard daemon for automatic prevention:
pip install cozempic && cozempic initcompact-summary-collapsealone saves 85-95% on compacted sessions. Combined withimage-strip,progress-collapse, anddocument-dedup, you should see that 74MB drop to single-digit MB.junaidtitan commentedon Apr 6, 2026
74MB transcript triggering the false rate limit is a session size problem. Cozempic v1.6.11 can dramatically reduce that — aggressive prescription runs 18 strategies.
compact-summary-collapsealone saves 85-95%. The guard daemon prevents files from ever reaching that size.pip install cozempic && cozempic initrwp65 commentedon Apr 10, 2026
ANTHROPIC - WHY HAS THIS NOT BEEN ASSIGNED TO SOMEONE TO FIX??????????
github-actions commentedon May 24, 2026
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
github-actions commentedon Jul 16, 2026
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.