`${CLAUDE_PLUGIN_ROOT}` is not expanded for `statusLine.command` (works for hooks/MCP/LSP/monitors)
Version: Claude Code 2.1.117 (also reproduced on 2.1.112), macOS 15
Summary
The plugins reference documents ${CLAUDE_PLUGIN_ROOT} as a variable expanded inside plugin component commands. In practice the variable is populated for hook, MCP, LSP, and monitor subprocesses, but absent from the statusLine.command subprocess. Plugins that follow the documented pattern silently render no statusline.
Scope
The bug is specific to the statusLine subprocess environment. The same plugin's hooks resolve ${CLAUDE_PLUGIN_ROOT} correctly. So this is not a general plugin-variable expansion issue — it is a missing-env case for statusLine specifically.
Reproduced with derjochenmeyer/claude-code-craft-statusline.
Reproducer
- Install any plugin that ships a renderer at
<plugin-root>/scripts/foo.sh. - In
~/.claude/settings.json:
\\\json\
\"statusLine\": {
\"type\": \"command\",
\"command\": \"\${CLAUDE_PLUGIN_ROOT}/scripts/foo.sh\"
}
\\
- No statusline appears.
Diagnostic trace
Wrapping the statusLine command with a logger that dumps \env\ reveals \CLAUDE_PLUGIN_ROOT\ (and \CLAUDE_PLUGIN_DATA\) are absent from the statusLine subprocess, and the plugin's \bin/\ directory is not in \PATH\ either:
\\\`
--- ENV (CLAUDE/PLUGIN only) ---
CLAUDE_CODE_ENTRYPOINT=cli
CLAUDE_CODE_NO_FLICKER=1
CLAUDE_PROJECT_DIR=<project>
--- plugin bin dirs in PATH ---
(none)
--- RENDERER raw=/scripts/foo.sh ---
RENDERER_RESOLVED=missing (CLAUDE_PLUGIN_ROOT not expanded)
\\\`
Expected
\\${CLAUDE_PLUGIN_ROOT}\ (and ideally \\${CLAUDE_PLUGIN_DATA}\) should be populated in the statusLine subprocess environment, matching the behavior already in place for hooks, MCP servers, LSP servers, and monitors. Alternatively, please document the limitation explicitly so plugin authors do not rely on it.
Workaround until fixed
POSIX shell default expansion in the command string works, since the statusline docs state the command runs in a shell:
\\\json\
\"command\": \"\${CLAUDE_PLUGIN_ROOT:-\$HOME/.claude/plugins/marketplaces/<marketplace>/scripts/foo.sh}\"
\\
The \marketplaces/\ clone path is version-stable across plugin updates. Once the variable is properly populated, the same line transparently uses the official plugin root.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗