[BUG] 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

Resolved 💬 10 comments Opened Mar 29, 2026 by rwp65 Closed May 24, 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?

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

  1. Run a Claude Code session for multiple days with heavy agent usage (many subagent dispatches, large code changes)
  2. Accumulate a conversation transcript of ~74MB (the .jsonl file grows as the session continues)
  3. Leave the session idle for several hours
  4. Send any message (e.g., "proceed")
  5. 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

  1. Run a Claude Code session for multiple days with heavy agent usage (many subagent dispatches, large code changes)
  2. Accumulate a conversation transcript of ~74MB (the .jsonl file grows as the session continues)
  3. Leave the session idle for several hours
  4. Send any message (e.g., "proceed")
  5. 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

  1. 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.
  2. If rate limiting must include context, reset the budget after idle periods — hours of inactivity should fully reset any per-minute/per-hour budget.
  3. 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 /compact or a fresh session."
  4. Distinguish client-side rate limiting from API rate limiting — the current message is identical for both, making it impossible for the user to diagnose.

View original on GitHub ↗

This issue has 10 comments on GitHub. Read the full discussion on GitHub ↗