[BUG] statusLine command receives "high" instead of "xhigh" for effort level

Status Fixed / completed
Reported on v2.1.179
Maintainer reply None cached
Activity 5 comments · opened Jun 17, 2026 · closed Aug 20, 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?

When effort is configured to xhigh, the JSON passed to a statusLine command reports "level": "high" in the .effort.level field instead of "xhigh". This makes it impossible for a status line script to distinguish between high and xhigh effort.

What Should Happen?

Expected: .effort.level = "xhigh"
Actual: .effort.level = "high"

Error Messages/Logs

Steps to Reproduce

  1. Set effort to xhigh (/effort xhigh)
  2. Configure a statusLine command that reads .effort.level from the piped JSON
  3. Observe the value is "high", not "xhigh"

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.179 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

4 Comments

github-actions[bot] · 2 months ago

Found 1 possible duplicate issue:

  1. https://github.com/anthropics/claude-code/issues/69068

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

cfchris · 2 months ago

I don't think this is a duplicate of #69068

Conversation w/ my Claude Code:

There it is - Claude Code is actually sending "high" in the JSON even though your session is set to xhigh. This is a bug in Claude Code's status line data, not in your script.

Your script is correct and already handles xhigh - the problem is upstream. I'd recommend filing a bug at https://github.com/anthropics/claude-code/issues linking to issue 69068, since the
docs say xhigh should be reported but the actual JSON payload is collapsing it to high.

Let me remove the debug logging now:

⏺ Update(~/.claude/statusline-command.sh)
⎿ Removed 1 line
8 # Color: only the ctx bar is colored, by usage band (<30 green, 30-59 yellow, >=60 orange).
9
10 input=$(cat)
11 -echo "$input" > /tmp/statusline-debug.json
11
12 model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
13 model=${model#Claude } # "Claude Opus 4.8" -> "Opus 4.8"

⏺ And I'll save a memory so I don't repeat the bad claim in a future session:

Recalled 1 memory, wrote 2 memories (ctrl+o to expand)

⏺ Confirmed: Claude Code bug. The JSON sends "high" when the session is xhigh. Your script is fine. Worth filing on that issue if you want it tracked.

✻ Crunched for 47s

❯ I filed a bug. They're trying to close it as a duplicate of one related to "ultra code". But, I think this is a different issue.

⏺ The distinction is clear: the ultracode issue is about ultracode not reporting as xhigh. Your issue is the inverse - you explicitly set /effort xhigh (no ultracode involved at all) and the
field still comes back as "high". Different trigger, different reproduction path.

The argument for keeping it open: your repro is simpler and more direct. You can reproduce it with just /effort xhigh in a plain session - no ultracode, no keyword needed. If the ultracode
fix only addresses the ultracode path, /effort xhigh could remain broken after that fix ships.

Worth commenting on the issue with exactly that framing: "This reproduces without ultracode - just /effort xhigh in a normal session. The status line JSON returns \"level\": \"high\". If
the duplicate fix only addresses the ultracode path, this case may still be broken after it lands."

cfchris · 2 months ago

Oh, this may be a slightly different bug. The bug might be that Claude Code /effort lets you select "xhigh" for Sonnet. But, Sonnet tops out at "high".

Conversation w/ Claude Code:

OK. Wait. Why does "effort xhigh ●●●●○" show up when the model is Opus and not when it's Sonnet?

⏺ Good question. Let me get you an authoritative answer rather than guess at the exact gating logic.

⏺ claude-code-guide(Why effort indicator shows on Opus not Sonnet)
⎿ Done (6 tool uses · 36.5k tokens · 33s)
(ctrl+o to expand)
⎿ Allowed by auto mode classifier

⏺ Short version: it's a model-capability thing, not a bug.

The effort chip in Claude Code is tied to how many effort tiers the active model supports, and which one you've selected:

  • Opus 4.7 / 4.8 and Fable 5 support the full ladder: low / medium / high / xhigh / max. Since you set xhigh — a tier these models actually have — Claude Code shows the chip with the dots

filled to that level (●●●●○).

  • Sonnet 4.6 (and Opus 4.6) top out at high and don't have a native xhigh. When you're on Sonnet, the xhigh you picked silently falls back to high, so the UI suppresses the "effort xhigh"

chip rather than advertising a level the model can't run.

In other words, the chip reflects your selected tier as actually applied to the current model. On Opus, xhigh is real, so it renders. Switch to Sonnet and xhigh collapses to plain high
(which is also Sonnet's default), so there's nothing distinctive to show and the chip drops off.

If you want the chip to stay visible on Sonnet, you'd need to be on a tier it genuinely supports — but note high is already its default, so there's no higher gear to engage there.

One caveat worth flagging given your setup: this built-in chip is separate from your custom statusline effort display, which has that known upstream bug where Claude Code reports "high" in
the status-line JSON even when effort is actually xhigh. So don't be surprised if your custom statusline and this built-in chip disagree on Opus — the script is correct; the JSON it's fed
is wrong.

puffdad75 · 1 month ago

Same root cause appears to affect max as well, not just xhigh.

Setup:

  • Claude Code v2.1.206, Windows
  • Custom statusLine script reads .effort.level from stdin JSON

Repro:

  1. Run /model and select max effort. Confirmation toast correctly reads: "Set model to [Model] and saved as your default for new sessions with max effort" — so the setting itself registered correctly.
  2. statusLine's .effort.level field still reports "high" instead of "max".
  3. The in-task effort indicator (e.g. "thinking with high effort" shown next to the spinner while a task is running) also shows high instead of max.

This looks like the same serialization bug as the xhigh case reported here — the backend appears to cap .effort.level at "high" for any level above it (xhigh, max), rather than passing the actual configured value through to the statusLine hook and in-task UI.

Showing cached comments. Read the full discussion on GitHub ↗