[MODEL] Should not encourage shell command substitution `$(...)` in system prompt — causes permission approval dialog spam

2 min read Original article ↗

Preflight Checklist

  • I have searched existing issues for similar behavior reports
  • This report does NOT contain sensitive information (API keys, passwords, etc.)

Type of Behavior Issue

Claude's behavior changed between sessions

What You Asked Claude to Do

Recent versions of Claude Code increasingly use shell command substitution ($(...))
in generated commands — apparently encouraged by the system prompt itself.
However, any command containing $(...) always triggers a manual permission
approval dialog
, regardless of allow rules defined in settings.json.
This results in approval dialog spam for otherwise-allowed commands.

Background

Claude Code's permission system correctly treats shell command substitution as
requiring explicit approval (reasonable from a security perspective).
However, the system prompt appears to encourage patterns like:

git commit --message "$(cat << 'EOF'
...
EOF
)"

This means even commands covered by allow rules (e.g. Bash(git commit:*))
always prompt for manual approval, defeating the purpose of the allowlist entirely.

What Claude Actually Did

I have added Bash(git commit:*) to the allow list in ~/.claude/settings.json

  1. Let Claude Code to perform a git commit
  2. Claude generates: git commit -m "$(cat << 'EOF' ...)"
  3. Permission approval dialog appears every time, despite the allowlist entry

Expected Behavior

Claude Code should use allowlist-compatible command forms, e.g.:

git commit -m "1st line" -m "2nd line"

This would respect the Bash(git commit:*) allow rule and avoid unnecessary prompts.

Files Affected

Permission Mode

Accept Edits was ON (auto-accepting changes)

Can You Reproduce This?

Yes, every time with the same prompt

Steps to Reproduce

As written in the What Claude Actually Did section

Claude Model

Opus

Relevant Conversation

Impact

Low - Minor inconvenience

Claude Code Version

v2.1.70

Platform

Anthropic API

Additional Context

When asked to stop using this pattern, Claude Code itself acknowledged that shell command substitution ($(...)) is directed by its system prompt.

Adding an explicit instruction to CLAUDE.md to avoid shell command substitution
partially mitigates the issue, but it requires strong phrasing and is not reliable —
the system prompt appears to override user instructions in CLAUDE.md.

The proper fix should be in the system prompt itself.