Claude Code commit guards never fire: $TOOL_INPUT is unset
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 65/100
Research direction
Read .claude/settings.json and the Claude Code hooks reference linked in the issue; the issue includes reproductions for the failing guards and the proposed stdin parsing change. Check how the guards behave for the bypass spellings listed, including git -C . commit and git commit -am with an unstaged secret. Done when the guards block the described staged cases and the issue's bypass cases are covered by a CI check.
Written by the indexing model from the issue text.
Description
The two PreToolUse guards on Bash in .claude/settings.json (sensitive files and secrets in a commit) exit 2 correctly, but they can't fire: they read $TOOL_INPUT, which Claude Code doesn't set. The call arrives as JSON on stdin (hooks reference: "For command hooks, input arrives on stdin"), so grep -q 'git commit' never matches and both exit 0. Their messages also go to stdout; Claude Code shows a blocking hook's stderr, so Claude wouldn't see why.
A fix that keeps your checks and messages:
{ "type": "command", "command": "if jq -r \".tool_input.command // empty\" | grep -q 'git commit'; then git diff --cached --name-only | grep -E '\\.(env|pem|key|p12)$' && echo '⛔ BLOCKED: Sensitive file in commit' >&2 && exit 2 || exit 0; fi" },
{ "type": "command", "command": "if jq -r \".tool_input.command // empty\" | grep -q 'git commit'; then git diff --cached | grep -iE '(api_key|password|secret|token|nyk_v0)' && echo '⛔ BLOCKED: Possible secret in commit' >&2 && exit 2 || exit 0; fi" }
Tested with the JSON Claude Code sends, in a scratch repo with a staged prod.env and a staged api_key = "..." line: today git commit -m wip exits 0 from both guards. With the fix both exit 2, and git status still passes.
With the fix in place, I also ran it against a few spellings agents produce for the same action. Verified: each of these exits 0, so the commit goes ahead: git -C . commit -m wip, and git commit -am wip when the secret is in an unstaged change to a tracked file (the scan reads only what is already staged, and -a stages the rest at commit time).
Would a check like this be useful in CI, one that runs your guards against bypass spellings and fails the build when one gets through?
Found this while testing Claude Code hooks for Paveo, which I build (open source). Happy to open a PR with the fix.
- Dominant language
- Go
- Stars
- 75
- Forks
- 2
- Avg merge
- 16d 4h
- Merged PRs (30d)
- 1
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nylas/cli
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
`XOAUTH2` / `OAUTHBEARER` supportMay be free again @qasim-nylas claimed this 152 days ago, and no pull request is open. Openbug enhancement
Similar issues
-
good first issue help wanted v3
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
oras-project/oras-go#1621 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
Maintainers usually reply within 4 days
-
Chained slog With calls discard previously bound attributesPossibly taken @yuefdev claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
[scanner] TestAgentNowLineStates hard-fails instead of degrading when node is off PATHPossibly taken @arteeh claimed this today. Openagent/scanner ci help wanted kind/test
Difficulty 1/5 Under an hour Newbie friendliness 90/100
hivecommons/hive#12924 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Gentleman-Programming/engram#1940 ·
Maintainers usually reply within 1 day