[Bug] Permission matcher ignores piped commands, breaking Bash(cmd:*) allowlist rules
Bug Description
Title: Permission matcher doesn't handle piped commands — Bash(cmd:*) misses cmd …
| tail, forcing unnecessary permission prompts (v2.1.119, Agent Teams)
Version: 2.1.119
Platform: macOS 15.5, iTerm2 stable, zsh
Related to: The <Box> can't be nested inside <Text> Ink crash bug (filed
separately) — this bug makes that one fire more often than it needs to.
Summary:
.claude/settings.local.json permissions.allow entries like Bash(python3:*) or
Bash(/abs/path/to/python3:*) match direct invocations but NOT piped variants. A
teammate that pre-allowlisted python3:* still triggers a permission prompt when it
calls python3 -c "..." 2>&1 | head -50. The user already trusted python3; piping
its output to head shouldn't re-gate it. Combined with the Ink rendering bug, every
unnecessary permission prompt is a potential teammate crash.
Repro:
- .claude/settings.local.json has "allow": ["Bash(python3:*)",
"Bash(/Users/.../venv/bin/python3:*)"]
- Spawn a teammate with --permission-mode auto
- Teammate runs: python3 -c "print(1)" — ✅ no prompt (matches)
- Teammate runs: python3 -c "print(1)" 2>&1 | head -50 — ❌ permission prompt
fires
- Teammate runs: python3 -c "print(1)" > /tmp/out — ❌ permission prompt fires
Real-world impact:
SIT v5.6 sleeve teammates commonly pipe Python/SQL output through head/tail/grep
for readable output. Every such command hits a permission prompt. On v2.1.119 +
--teammate-mode tmux, some of those prompts trigger the Ink nesting crash and kill
the teammate pane. Pre-allowlisting is impractical because the combinatorial space
of pipe variants is huge.
Related observations:
- Read also needs permission for any path outside the project cwd, with no simple
wildcard. Allowlisting Read(/tmp/**) works but shouldn't be needed for files the
agent writes itself in the same turn.
- With --permission-mode auto, MCP tool calls are auto-approved when
pre-allowlisted (good), but Bash isn't — creating a strong incentive to use MCP
tools even when shell would be more natural.
Requests:
- Extend Bash(cmd:*) matching to pipelines and simple redirects. If all commands
in the pipeline are allowlisted (or are common safe utilities like head, tail,
grep, wc, sort, uniq, jq, awk, sed), the whole pipeline should auto-approve. Denied
commands in the pipeline still block.
- Consider a Bash(*:allow-pipes) modifier so users can explicitly opt into
pipeline-safe handling per rule, instead of guessing an ever-growing pattern list.
- Document the matcher semantics. Current behavior (pipeline breaks prefix match)
is not documented anywhere I could find, and nothing in the UI explains why a
pre-allowlisted command still prompted.
Environment Info
- Platform: darwin
- Terminal: iTerm.app
- Version: 2.1.119
- Feedback ID: c682269b-aa50-4c8b-a40e-c5d66a111719
Errors
[{"error":"Error: Plugin MCP server error - mcp-config-invalid: MCP server github invalid: Missing environment variables: GITHUB_PERSONAL_ACCESS_TOKEN\n at TWH (/$bunfs/root/src/entrypoints/cli.js:2736:30496)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-04-24T03:33:53.938Z"},{"error":"Error: Tool mcp__PAL__listmodels not found\n at Uj7 (/$bunfs/root/src/entrypoints/cli.js:3077:31268)\n at kz (/$bunfs/root/src/entrypoints/cli.js:484:21134)\n at P1 (/$bunfs/root/src/entrypoints/cli.js:484:39900)\n at M9H (/$bunfs/root/src/entrypoints/cli.js:484:50713)\n at rZH (/$bunfs/root/src/entrypoints/cli.js:484:87780)\n at RD6 (/$bunfs/root/src/entrypoints/cli.js:484:86738)\n at iZH (/$bunfs/root/src/entrypoints/cli.js:484:86558)\n at jM_ (/$bunfs/root/src/entrypoints/cli.js:484:82889)\n at aH (/$bunfs/root/src/entrypoints/cli.js:484:6552)\n at LH (/$bunfs/root/src/entrypoints/cli.js:484:5006)\n at async <anonymous> (/$bunfs/root/src/entrypoints/cli.js:18721:2361)","timestamp":"2026-04-24T03:33:55.083Z"},{"error":"Error: Tool mcp__debate__listmodels not found\n at Uj7 (/$bunfs/root/src/entrypoints/cli.js:3077:31268)\n at kz (/$bunfs/root/src/entrypoints/cli.js:484:21134)\n at P1 (/$bunfs/root/src/entrypoints/cli.js:484:39900)\n at M9H (/$bunfs/root/src/entrypoints/cli.js:484:50713)\n at rZH (/$bunfs/root/src/entrypoints/cli.js:484:87780)\n at RD6 (/$bunfs/root/src/entrypoints/cli.js:484:86738)\n at iZH (/$bunfs/root/src/entrypoints/cli.js:484:86558)\n at jM_ (/$bunfs/root/src/entrypoints/cli.js:484:82889)\n at aH (/$bunfs/root/src/entrypoints/cli.js:484:6552)\n at LH (/$bunfs/root/src/entrypoints/cli.js:484:5006)\n at async <anonymous> (/$bunfs/root/src/entrypoints/cli.js:18721:2361)","timestamp":"2026-04-24T03:33:55.084Z"},{"error"…
Note: Content was truncated.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗