Skip to content

[BUG] Invalid "Bash(*)" permission pattern blocks all npm/npx commands #477

@klappi91

Description

@klappi91

Bug Report: Invalid "Bash(*)" permission pattern blocks all npm/npx commands

Description

AutoClaude uses "Bash(*)" in .claude_settings.json, which is invalid syntax according to Claude Code's IAM documentation. This causes all npm/npx/node commands to be blocked, even though the code comments suggest the bash_security_hook should handle validation.

Location

  • File: apps/backend/core/client.py
  • Line: 294
  • Branch: develop

Current (Broken) Code

security_settings = {
    "permissions": {
        "allow": [
            # ...
            "Bash(*)",  # ❌ INVALID - no command prefix!
            # ...
        ]
    }
}

Expected Code

security_settings = {
    "permissions": {
        "allow": [
            # ...
            "Bash(npm:*)",
            "Bash(npx:*)",
            "Bash(node:*)",
            "Bash(python3:*)",
            "Bash(pnpm:*)",
            "Bash(yarn:*)",
            # Or dynamically from PACKAGE_MANAGER_COMMANDS
            # ...
        ]
    }
}

Evidence

  1. Claude Code Documentation: https://code.claude.com/docs/en/iam.md

    "Bash permission patterns use prefix matches. The wildcard :* only works at the end of a pattern to match any continuation."

  2. Valid Examples from Docs:

    • Bash(npm run test:*)
    • Bash(git:*)
    • Bash(*) ❌ (no command prefix)

Impact

  • All npm/npx/node commands fail with: "Command 'npm' is not in the allowed commands for this project"
  • bash_security_hook is never executed (Bash tool itself is blocked)
  • Users must manually fix .claude_settings.json in every worktree

Reproduction

  1. Start any AutoClaude task
  2. Try to run npx create-next-app
  3. Command is blocked despite sandbox enabled

Proposed Fix

Replace "Bash(*)" with proper prefix patterns:

Option 1: Static list

"allow": [
    "Bash(npm:*)",
    "Bash(npx:*)",
    "Bash(node:*)",
    "Bash(python3:*)",
    # ... from BASE_COMMANDS + detected package managers
]

Option 2: Dynamic (recommended)

# Build from PACKAGE_MANAGER_COMMANDS + BASE_COMMANDS
bash_permissions = []
for pm in detected_package_managers:
    for cmd in PACKAGE_MANAGER_COMMANDS[pm]:
        bash_permissions.append(f"Bash({cmd}:*)")

for cmd in BASE_COMMANDS:
    bash_permissions.append(f"Bash({cmd}:*)")

security_settings = {
    "permissions": {
        "allow": [
            *bash_permissions,
            # ...
        ]
    }
}

Workaround

Users can manually fix .claude_settings.json with:

{
  "permissions": {
    "allow": [
      "Bash(npm:*)",
      "Bash(npx:*)",
      "Bash(node:*)"
    ]
  }
}

Related Issues

Environment

  • AutoClaude version: 2.7.1
  • OS: All platforms (Linux/macOS/Windows)
  • Claude Code: Latest version

Additional Context

The code includes this comment:

# Bash permission granted here, but actual commands are validated
# by the bash_security_hook (see security.py for allowed commands)

However, the permission is NOT actually granted because "Bash(*)" is invalid syntax. The security hook never gets a chance to run because the Bash tool itself is blocked at the permission level.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions