[BUG] --disallowedTools and --tools cause silent 0-cost exit in pipe mode when combined with --mcp-config + large --append-system-prompt

Resolved 💬 3 comments Opened Mar 8, 2026 by piersdd Closed Mar 11, 2026

Description

When using claude -p (pipe mode) with --disallowedTools or --tools combined with --mcp-config and a large --append-system-prompt (~18KB+), Claude Code exits immediately with code 0, produces no output, and consumes no tokens.

Removing the --disallowedTools/--tools flag while keeping all other flags unchanged produces the expected response.

Reproduction

# 1. Create a large system prompt file (~18KB)
cat > /tmp/large-prompt.txt << 'PROMPT'
# Vault Reference — Universal Architecture and Conventions
# ... (paste ~18KB of system prompt content) ...
PROMPT

LARGE_PROMPT=$(cat /tmp/large-prompt.txt)

# 2. Create a minimal MCP config with at least one server
cat > /tmp/mcp.json << 'MCP'
{
  "mcpServers": {
    "example": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/mcp-server-memory"]
    }
  }
}
MCP

# 3. This WORKS — produces output, consumes tokens:
claude -p \
  --model claude-sonnet-4-6 \
  --append-system-prompt "$LARGE_PROMPT" \
  --output-format json \
  --mcp-config /tmp/mcp.json \
  --no-session-persistence \
  -- "Say hello"

# 4. This SILENTLY EXITS — 0 exit code, no output, no tokens:
claude -p \
  --model claude-sonnet-4-6 \
  --append-system-prompt "$LARGE_PROMPT" \
  --output-format json \
  --mcp-config /tmp/mcp.json \
  --disallowedTools "Edit,Write" \
  --no-session-persistence \
  -- "Say hello"

Key observation: The --disallowedTools flag uses variadic parsing (<tools...>). When combined with a large system prompt and MCP config, it appears to either consume the subsequent arguments or trigger an early exit path. Adding -- before the prompt (to separate variadic args from the positional prompt) resolves the argument parsing issue but the silent exit persists with MCP + large prompt.

Observed behaviour

  • Exit code: 0
  • stdout: empty
  • stderr: empty
  • API cost: $0.00 (no tokens consumed — the request never reaches the API)
  • No error message of any kind

Expected behaviour

Claude should process the prompt normally, applying the tool restrictions, and return a response. If the flag combination is unsupported, it should exit with a non-zero code and an error message.

Environment

  • Claude Code version: 2.1.66
  • OS: macOS 15.4 (Darwin 25.3.0), Apple Silicon
  • Node: v22.x (Nix-managed)
  • Shell: zsh
  • Installation: Nix package (pkgs.claude-code)

Workaround

Remove --disallowedTools / --tools flags. Operators run with default tool permissions. MCP tool access is still scoped via settings.json auto-approval list, but built-in tools (Bash, Edit, Write) cannot be restricted.

Additional context

This was discovered while building a generic operator dispatch system using claude -p with LaunchAgents. The intent was to sandbox operators by denying destructive tools (e.g., deny Write/Edit for a read-only operator, deny Bash for a vault-only operator). The combination of:

  • --mcp-config (4 MCP servers)
  • --append-system-prompt (~18KB operator identity prompt)
  • --disallowedTools (tool restriction)

reliably produces the silent exit. Removing any one of these flags changes the behaviour (e.g., without --mcp-config, --disallowedTools works fine with the large prompt).

Related: #25589 (--disallowedTools not affecting MCP tools — different bug, but same flag).

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗