Shell variable expansion broken in piped commands due to HLD tokenizer re-quoting
Bug Description
When a Bash tool command contains a pipe (|), shell variable references like $JIRA_TOKEN inside double-quoted arguments are not expanded. The same command works correctly without a pipe.
Root Cause
The CLI has two code paths for processing commands before eval:
- No pipe (
oAD): Escapes the entire command string as one unit. Aftereval, the original double-quoting is preserved, so$VARexpands correctly. - With pipe (
HLD): Tokenizes the command, strips the original quoting, then re-escapes each token individually with single quotes viaID(). This converts"Authorization: Bearer $JIRA_TOKEN"→'Authorization: Bearer $JIRA_TOKEN', preventing variable expansion.
Reproduction
# Using the Bash tool in Claude Code:
# ✅ Works (no pipe → oAD path)
curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $MY_TOKEN" https://example.com/api
# ❌ Fails - $MY_TOKEN not expanded (pipe → HLD path)
curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $MY_TOKEN" https://example.com/api | cat
Expected Behavior
$MY_TOKEN should be expanded in both cases, since it is inside double quotes.
Actual Behavior
In the piped command, $MY_TOKEN is passed as the literal string $MY_TOKEN because HLD's tokenize-then-reconstruct process replaces the original double quotes with single quotes.
Impact
This commonly affects API calls where Claude adds a pipe for pretty-printing (e.g., | python3 -m json.tool), causing authentication headers with $ENV_VAR references to be sent unexpanded, resulting in 401 errors.
Environment
- Claude Code v2.1.71 (VS Code extension, linux-x64)
- Shell:
/bin/bash5.2.37
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗