Skip to content

Claude Code guard for destructive commands never blocks: $CLAUDE_TOOL_INPUT is not set, and exit 1 doesn't block #547

Open

Description

@faizjamal0111-svg

The PreToolUse hook in .claude/settings.json is meant to stop rm -rf, DROP TABLE and --force, but it never blocks anything, for two reasons:

  1. Claude Code passes the tool call to a hook as JSON on stdin. It does not set $CLAUDE_TOOL_INPUT (the hooks reference lists the variables it does set), so the grep never matches.
  2. Even on a match, exit 1 would not block. For PreToolUse only exit code 2 blocks; the reference says Claude Code "treats exit code 1 as a non-blocking error and proceeds with the action."

I checked both with Claude Code 2.1.292: inside a hook CLAUDE_TOOL_INPUT is empty, and this hook, given the JSON Claude Code sends for rm -rf build, exits 0.

A fix that keeps your pattern:

"command": "grep -qE 'rm -rf|DROP TABLE|--force' && { echo 'BLOCK: destructive command' >&2; exit 2; } || true"

With the same input this exits 2 for rm -rf build and 0 for ls.

Found this while testing Claude Code guards for Paveo. Happy to open a PR with the fix.

Activity

  1. a943314777-star commented on Oct 23, 2026

    @a943314777-star

    Thanks for the concrete reproduction. I maintain a small local checker for a few destructive command patterns and Claude Code PreToolUse setup. It includes doctor.js to check that a settings file points to the expected hook, plus a harmless deny/ask/clear probe. It does not fix exit-code semantics or prove that the host loaded the hook, so /hooks and a disposable-project test are still required. If useful, would you try it in a throwaway repo and tell me whether the setup check catches anything useful? https://tubular-vacherin-d69b0f.netlify.app/ No repository access, production commands, or secrets are needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions