Skip to content

confirm-deploy PreToolUse hook hard-blocks non-deploy Bash commands (incl. /lua-doctor's own 'lua agents' probe) #2

Description

@Nelnamara

Summary

The confirm-deploy PreToolUse Bash hook intermittently hard-blocks legitimate Bash commands that do not invoke lua deploy — including the plugin's own /lua-doctor Step 4 probe (lua agents --json --ci). Because confirm-deploy.decide() blocks anything that isn't a prefixed lua deploy, any command whose if scoping is mis-matched is rejected with DEPLOY_DENIED_BARE.

Environment

  • Claude Code on Windows 11 (Git Bash shell)
  • Plugin lua-agent-builder 1.0.0 (claude-code-lua-plugin marketplace)
  • lua-cli 3.18.0, Node v24.16.0, npm 11.13.0

Relevant hooks/hooks.json

{ "matcher": "Bash",
  "hooks": [{ "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/confirm-deploy.mjs",
              "if": "Bash(*lua deploy*)" }] }

Observed

Command Result
node --version ✓ passes
lua --version ✓ passes
lua agents --json --ci blocked (DEPLOY_DENIED_BARE)
multi-line ls … && ls … && … (no lua token at all) blocked

The blocked commands contain no lua deploy substring. Simple single-token commands pass; commands with an env prefix (PATH=… lua agents), pipes, && chains, or spaces in paths appear to trip the if scoping into firing.

Why allow rules don't save it

The user's settings.json explicitly allows Bash(lua agents *), but PreToolUse hooks run regardless of permissions.allow, so the misfiring hook overrides the allow rule. The result is a hard block with no way to proceed except routing the command through a different shell (PowerShell).

Impact

  • Legitimate lua subcommands and general Bash are intermittently hard-blocked.
  • /lua-doctor cannot complete Step 4 — its own lua agents auth probe is blocked by the plugin's own hook.

Suggested fix

  • Tighten the if matcher to anchor on an actual lua deploy invocation (token / word-boundary match) rather than the substring glob Bash(*lua deploy*), or
  • Make confirm-deploy.decide() return null (allow) unless the command actually invokes the deploy subcommand, instead of blocking every non-prefixed-deploy command it sees.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions