[BUG] PreToolUse hook `updatedInput` is silently ignored for the Bash tool
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?
Bug report: PreToolUse hook updatedInput is silently ignored for the Bash tool
Claude Code version: 2.1.215 (desktop app)
Area: PreToolUse hooks — hookSpecificOutput.updatedInput on the Bash tool
Summary
A PreToolUse hook that returns permissionDecision: "allow" together withupdatedInput to rewrite a Bash command has no effect — the original,
unrewritten command runs. This holds even for a single hook (no sibling
interaction required), and even when every matching hook emits updatedInput
and none emits an empty/no-updatedInput response.
The documented behavior is that updatedInput modifies the tool's input
parameters. For the Bash tool in this build, it is silently dropped.
Isolation (this was verified by elimination, not assumed)
Setup: four PreToolUse hooks match Bash (a command-rewriter + three validator
hooks). Symptom: the rewriter's updatedInput never applies.
- Symptom: rewriter's
updatedInput(command →rtk <cmd>) never applied;
commands ran raw.
- Ruled out "empty-abstain sibling clobbers a rewriter": made all three
validator hooks emit an explicit decision-less envelope
{"hookSpecificOutput":{"hookEventName":"PreToolUse"}} instead of bare
exit 0. The rewrite still did not apply.
- Ruled out sibling interaction entirely (decisive): made ALL FOUR Bash
hooks emit updatedInput for one probe command (git status --probe →
echo MARKER), each with permissionDecision: "allow". No hook emitted a
no-updatedInput response. The probe command STILL executed raw
(git: unknown option 'probe') — neither the marker rewrite nor the proxy
rewrite applied.
Since no empty/abstaining response was present in step 3, sibling-clobbering
cannot explain it: updatedInput is simply not honored for the Bash tool in
this session. Each hook was confirmed to emit well-formed JSON when invoked
directly, so the hooks fired and their output was ignored.
Actual
The original command runs; updatedInput is silently discarded for Bash.
Impact
Any transparent Bash command-rewriter hook (proxies, token optimizers, sandbox
wrappers, redactors) silently no-ops. If the rewrite is a policy control, it's a
silent policy bypass with no signal to the user or the hook.
What Should Happen?
The hook's updatedInput.command is applied; the rewritten command runs.
Steps to Reproduce
Minimal, single hook
.claude/settings.json:
{"hooks":{"PreToolUse":[{"matcher":"Bash","hooks":[{"type":"command","command":"node rewrite.mjs"}]}]}}
rewrite.mjs:
process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:{command:"echo REWRITE_APPLIED"}}}));
Run any Bash command → expected REWRITE_APPLIED, actual: the original command runs.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.207 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Claude Code desktop app (Windows) — commands run via its Bash tool = Git Bash (MINGW64), not an interactive shell
Note vs. existing issues
- Distinct from #30770 (single hook's partial
updatedInputreplacing fields
instead of merging — closed not-planned). Here updatedInput has NO effect at
all.
- Distinct from #75915 (sibling returns
ask+ user approves →updatedInput
dropped). No ask and no prompt is involved here.
- Possibly related to #47853 ("
updatedInputsilently ignored for Edit — works
for Read and Bash"), but INVERTED: Bash is also ignored in this 2.1.215
desktop build. If Bash updatedInput is expected to work, this may be a
regression or a build/platform-specific defect.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗