[BUG] statusLine context_window.used_percentage drops to 0 after an API error: synthetic assistant entries carry all-zero usage

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

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (related, but a different trigger: #62768 for the one-tick zero after /compact, and #18241 for a percentage mismatch)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

When a turn fails with an API error (for example API Error: Can't reach the API server — check your internet or DNS (ENOTFOUND)), or when Claude Code writes No response requested., it appends a synthetic assistant message ("model": "<synthetic>") to the transcript. Every usage field on it is zero.

The statusLine payload takes context_window.used_percentage (and current_usage) from the last assistant message that has usage, and that is now the synthetic one. So the status line reports 0% context, and it keeps reporting 0% until the next successful reply. That can be hours: a session that sits idle after an outage shows "0% ctx" the whole time, while its real context is 200k–350k tokens.

/context is not affected. Only the statusLine payload is.

What Should Happen?

Synthetic entries (or any assistant entry whose input + cache usage total is 0) should be skipped when computing used_percentage and current_usage, so the value stays at the last real usage. Alternatively, send null ("unknown") instead of 0.

Error Messages/Logs

Sanitized transcript evidence from one machine, last 24h: 52 transcripts, 21 synthetic assistant entries, all 21 with all-zero usage (18 × the ENOTFOUND API error, 3 × "No response requested."). Three examples, each with the context of the previous real assistant message:

[
 {"ts": "2026-10-10T12:21:26.832Z", "text": "API Error: Can't reach the API server — check your internet or DNS (ENOTFOUND)",
  "usage": {"input_tokens": 0, "output_tokens": 0, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0},
  "prev_real_context_tokens": 294839},
 {"ts": "2026-10-10T08:24:50.689Z", "text": "No response requested.",
  "usage": {"input_tokens": 0, "output_tokens": 0, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0},
  "prev_real_context_tokens": 215736},
 {"ts": "2026-10-10T09:45:31.728Z", "text": "API Error: Can't reach the API server — check your internet or DNS (ENOTFOUND)",
  "usage": {"input_tokens": 0, "output_tokens": 0, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0},
  "prev_real_context_tokens": 354472}
]

(prev_real_context_tokens = input + cache_read + cache_creation of the last non-synthetic assistant message before it.)

Steps to Reproduce

  1. Configure a statusLine command that prints context_window.used_percentage from stdin.
  2. Work in a session until the context is clearly non-empty (e.g. 30%+).
  3. Make the next request fail with a network error (e.g. block the API host or go offline), so the turn ends with API Error: Can't reach the API server ….
  4. Restore the network and do not send another prompt.
  5. The status line now shows 0 and stays at 0 until the next successful reply. The transcript's last assistant entry has "model": "<synthetic>" and all-zero usage.

Claude Model

Not model-specific (the synthetic entry is written client-side).

Is this a regression?

Unknown.

Claude Code Version

2.1.296 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other (Ghostty-based terminal), zsh

Additional Information

Our workaround: when the payload reports a zero total or a null percentage, the statusLine script recomputes the value from the transcript. It takes the last non-synthetic, non-sidechain assistant usage after the last compact boundary and divides by context_window_size. It prints INDETERMINATE rather than 0% when it can't.

View original on GitHub ↗