[BUG] statusline-setup: printf format-injection from context %

Resolved 💬 3 comments Opened May 6, 2026 by dustfeather Closed Jun 4, 2026

Preflight

  • I have searched existing issues and this hasn't been reported yet (closest prior is #26309, closed-as-stale; the bot comment invites a new issue if still relevant).
  • This is a single bug report.
  • I am using the latest version of Claude Code (2.1.132).

What's Wrong?

The statusline-setup agent generates ~/.claude/statusline-command.sh whose final line embeds variables directly into a printf format string:

printf "${user_host}:${dir} [${model}${ctx_info}]"

ctx_info is built from context_window.used_percentage and ends in a literal %:

ctx_info=""
if [ -n "$used_pct" ]; then
  ctx_info=" ctx:$(printf '%.0f' "$used_pct")%"   # → e.g. " ctx:42%"
fi

Once Claude Code populates context_window.used_percentage in the input JSON, the format string becomes …[Opus 4.7 ctx:42%]. printf parses the trailing %] as an invalid format specifier, errors to stderr, and truncates stdout at the %. Claude Code consumes stdout and doesn't surface stderr, so the statusline silently breaks mid-session.

This is a latent bug: fresh sessions look fine because ctx_info is empty until used_percentage populates, so post-install verification passes. Users see the statusline disappear or look truncated some time later, with no visible error.

This is the same class of bug as #26309 (closed as stale). The original template was rewritten and that injection vector removed, but the new template reintroduced the underlying pattern of embedding %-bearing values into a printf format string.

What Should Happen?

Statusline should render the full string ending in ctx:42%] (with ANSI colors) regardless of whether used_percentage is present in the input JSON.

Error Messages/Logs

/home/<user>/.claude/statusline-command.sh: line 21: printf: `]': invalid format character

stdout is truncated at the %, so Claude Code receives a partial line.

Steps to Reproduce

  1. Run /statusline in Claude Code and let the statusline-setup agent generate the default script. Mine produced (for a green/blue PS1):

```bash
#!/usr/bin/env bash
input=$(cat)
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // "?"')
model=$(echo "$input" | jq -r '.model.display_name // "?"')
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')

user_host="\033[01;32m$(whoami)@$(hostname -s)\033[00m"
dir="\033[01;34m${cwd}\033[00m"

ctx_info=""
if [ -n "$used_pct" ]; then
ctx_info=" ctx:$(printf '%.0f' "$used_pct")%"
fi

printf "${user_host}:${dir} [${model}${ctx_info}]"
```

  1. Smoke-test with a JSON payload that includes used_percentage:

``sh
echo '{"workspace":{"current_dir":"/x"},"model":{"display_name":"Opus 4.7"},"context_window":{"used_percentage":42}}' \
| bash ~/.claude/statusline-command.sh
``

  1. Observe printf: '%]': invalid format character on stderr; stdout truncates at the %.
  1. In real use: the statusline displays correctly when a session starts but disappears or shows partial output once used_percentage becomes non-empty.

Suggested Fix

Change the final line to use %b (interprets backslash escapes for the ANSI colors but does NOT interpret % in the argument):

printf '%b' "${user_host}:${dir} [${model}${ctx_info}]"

| Format | \033 interpreted? | % in content treated as specifier? |
| --- | --- | --- |
| printf "$var" | yes | yes — bug |
| printf '%s' "$var" | no — colors break | no |
| printf '%b' "$var" | yes — colors work | no — safe |

%s would also fix the format-injection but breaks the \033 ANSI escapes in the variables, so colors stop rendering. %b is the correct choice.

More generally, the agent template should never use a variable as a printf format string — same advice as #26309.

Claude Code Version

2.1.132 (Claude Code)

Is this a regression?

I don't know. The injection vector here is in a template the agent writes from scratch each time, so whether it reproduces depends on which template version your install of statusline-setup produces. The closely-related #26309 covered an earlier template with the same class of bug.

Platform

Anthropic API.

Operating System

Other Linux (WSL2 — Linux 6.6.87.2-microsoft-standard-WSL2).

Terminal/Shell

WSL (Windows Subsystem for Linux), bash.

Additional Information

May be related but probably distinct: #44794 ("context percentage text intermittently disappears on re-render") — that one is platform:macos and labelled as a re-render issue rather than a script-template bug. Worth a triage glance to confirm they aren't the same root cause.

View original on GitHub ↗

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