Inline-shell rm check (2.1.288) asks on zsh -c scripts that contain no rm

Status Open
Reported on v2.1.288
Maintainer reply None cached
Activity 0 comments · opened Oct 3, 2026

Summary

Claude Code 2.1.288 added a check that looks inside sh -c / bash -c scripts for dangerous rm (#96300). It also applies to zsh -c, and it appears to parse the script as bash. When a zsh -c script evaluates a command that uses ordinary zsh syntax, the check asks:

This shell -c script runs rm and could not be checked

The script contains no rm. This prompt cannot be approved by a permission rule, so it stops auto mode and accept-edits mode, and an unattended session denies it after the timeout.

What happens

Claude Code 2.1.288, macOS, zsh 5.9.2. Each row is one Bash tool call.

| Command | Result |
|---|---|
| zsh -c 'eval "$1"' _ '[[ 12 == <-> ]] && echo num' | asks |
| zsh -c 'eval "$1"' _ 'echo num' | runs |
| zsh -c '[[ 12 == <-> ]] && echo num' | runs |
| bash -c 'eval "$1"' _ '[[ 12 =~ ^[0-9]+$ ]] && echo num' | runs |

<-> is zsh's numeric glob (matches any non-negative integer). It is not valid bash.

The same happens when a PreToolUse hook wraps every Bash command as zsh -c '…; eval "$1"' _ '<command>' (a common way to run commands in a configured zsh). Through such a wrapper we also saw:

| Wrapped command | Result |
|---|---|
| [[ 12 == <-> ]] && print num | asks |
| print -r -- '.{0,600}x' (single quote + brace pattern) | asks |
| print -r -- ".{0,600}x" | runs |
| print -r -- a{1,2} | runs |
| print -r -- $'x' | runs |
| print -r -- rm | runs |

The word rm plays no part: the same rows ask with or without it.

Expected

A zsh -c script is not judged by bash grammar. Either it is parsed as zsh, or a failure to parse zsh-only syntax does not by itself lead to "runs rm".

Why it matters

  • zsh is the default shell on macOS, and zsh -c with zsh syntax is ordinary.
  • The prompt says the script runs rm. A user approving it is told something that is not true of the script.
  • No permission rule can approve it, so a session that wraps commands in zsh is interrupted on ordinary commands with no supported way to say they are fine.

Not claimed

  • Which internal branch fires.
  • Why a quoted brace pattern asks through the wrapper, although quoted {0,600} is valid bash.

Related: #96300.

View original on GitHub ↗