Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Claude Code commit guards never fire: $TOOL_INPUT is unset

Open Beginner friendly
#128 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
65/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
github, go
Domain
cli, security

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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nylas/cli

All issues in nylas/cli

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.