claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Context percentage mismatch between /context, statusline API, and internal limit trigger

Open seanGSISG opened this issue 3 weeks ago • 1 comments

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?

Context percentage displays are inconsistent across different UI elements. The /context command and statusline JSON API show 67% used (31.7% free), but the built-in context warning on the right side of the status bar shows "2% remaining" and the system triggers "Context limit reached" even though there's ~63k tokens of free space available.

What Should Happen?

All context usage displays should show consistent percentages. If /context reports 67% used with 63k tokens free (31.7%), the status bar warning should also show ~33% remaining (not 2%), and Context limit reached should not trigger until context is actually near capacity.

Error Messages/Logs

`Context limit reached · /compact or /clear to continue`

This message appeared while /context showed:
`claude-opus-4-5-20251101 · 134k/200k tokens (67%)` | `Free space: 63k (31.7%)`

Steps to Reproduce

  1. Set autocompact to disabled in /config
  2. Start a long conversation (or continue an existing one) with Claude Code
  3. Work until the "Context limit reached" message appears
  4. Run /context command to see actual usage breakdown
  5. Compare the "Free space" percentage from /context with the "X% remaining" shown in the right side of the status bar

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.6

Claude Code Version

2.1.7

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

WSL2 with Wez-Term

Additional Information

Image Image

My statusline-command.sh

#!/bin/bash

# Read JSON input from stdin
input=$(cat)

# Parse JSON fields
MODEL=$(echo "$input" | jq -r '.model.display_name')
USED=$(echo "$input" | jq -r '.context_window.used_percentage // 0')
CWD=$(echo "$input" | jq -r '.workspace.current_dir')

# Get git info
BRANCH=$(git -C "$CWD" branch --show-current 2>/dev/null || echo "")
if [ -n "$BRANCH" ]; then
    git -C "$CWD" diff --quiet 2>/dev/null || DIRTY="*"
    GIT="${BRANCH}${DIRTY}"
else
    GIT=""
fi

# Build progress bar (10 characters wide)
BAR_WIDTH=10
FILLED=$(printf "%.0f" $(echo "scale=2; $USED * $BAR_WIDTH / 100" | bc 2>/dev/null || echo "0"))
[ -z "$FILLED" ] && FILLED=0
[ "$FILLED" -lt 0 ] 2>/dev/null && FILLED=0
[ "$FILLED" -gt "$BAR_WIDTH" ] 2>/dev/null && FILLED=$BAR_WIDTH
EMPTY=$((BAR_WIDTH - FILLED))

# Build the bar string with parallelograms
BAR=""
for ((i=0; i<FILLED; i++)); do BAR+="▰"; done
for ((i=0; i<EMPTY; i++)); do BAR+="▱"; done

# Output: Percentage | Model | Git | Progress Bar
PERCENT="${USED}%"
if [ -n "$GIT" ]; then
    printf "%s | %s | %s %s" "$PERCENT" "$MODEL" "$GIT" "$BAR"
else
    printf "%s | %s %s" "$PERCENT" "$MODEL" "$BAR"
fi

seanGSISG avatar Jan 14 '26 23:01 seanGSISG