claude-code - 💡(How to fix) Fix Slash-command preprocessor evaluates markdown inline-code-adjacent prose as zsh command substitution [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#56361Fetched 2026-05-06 06:30:11
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×4closed ×1commented ×1

Claude Code's slash-command preprocessor (the layer that reads `~/.claude/commands/*.md` when an operator types `/<command>`) appears to mis-parse markdown inline-code spans, treating prose between two adjacent inline-code spans (` `code1` ` and ` `code2` `) as a zsh command-substitution span (` `...` `) and eval-ing it through zsh. The eval typically fails on either the upstream `!` → `!` mangling that Claude Code's tool layer applies, OR zsh's NOMATCH glob behavior on `(...)` patterns, OR both simultaneously.

Error Message

Error: Shell command failed for pattern "!` to surface import failures loudly (IMP-5). The manifest existence check uses `": [stderr]

Root Cause

Claude Code's slash-command preprocessor (the layer that reads `~/.claude/commands/*.md` when an operator types `/<command>`) appears to mis-parse markdown inline-code spans, treating prose between two adjacent inline-code spans (` `code1` ` and ` `code2` `) as a zsh command-substitution span (` `...` `) and eval-ing it through zsh. The eval typically fails on either the upstream `!` → `!` mangling that Claude Code's tool layer applies, OR zsh's NOMATCH glob behavior on `(...)` patterns, OR both simultaneously.

Fix Action

Fix / Workaround

Workaround in user-space

The author-side workaround is rephrasing prose to avoid `(...)` between two inline-code spans (e.g., `(IMP-5)` → `per IMP-5`). This works but is brittle — operators have to know about the trigger pattern, and any new operator typing slash-command arguments containing parens hits the same parser path.

RAW_BUFFERClick to expand / collapse

Summary

Claude Code's slash-command preprocessor (the layer that reads `~/.claude/commands/*.md` when an operator types `/<command>`) appears to mis-parse markdown inline-code spans, treating prose between two adjacent inline-code spans (` `code1` ` and ` `code2` `) as a zsh command-substitution span (` `...` `) and eval-ing it through zsh. The eval typically fails on either the upstream `!` → `!` mangling that Claude Code's tool layer applies, OR zsh's NOMATCH glob behavior on `(...)` patterns, OR both simultaneously.

Reproduction

  1. Create a markdown command file at `~/.claude/commands/test-parser-trip.md` with content: ```markdown

    Test command

    The marker-read heredoc is wrapped with `if !` to surface import failures loudly (IMP-5). The manifest existence check uses `find_manifest_path` per CRIT-3. ```
  2. Invoke `/test-parser-trip` in Claude Code.
  3. Observe stderr: ``` Error: Shell command failed for pattern "!` to surface import failures loudly (IMP-5). The manifest existence check uses `": [stderr] (eval):1: no matches found: (IMP-5). ```

Expected behavior

Markdown inline-code spans (`` `...` ``) should be treated as opaque text by the slash-command preprocessor, not as zsh command-substitution boundaries. The prose between two adjacent inline-code spans is plain markdown text and should NOT be eval-ed through any shell.

Actual behavior

The preprocessor reads the closing backtick of inline-code #1 and the opening backtick of inline-code #2 as a paired zsh-style ` `...` ` (command substitution), and eval-s the prose between them. Two documented failure classes can fire:

  1. `!` mangling — Claude Code's tool layer escapes `!` to `!` upstream of the shell, even with `CLAUDE_CODE_SHELL=bash`. zsh \then errors with `condition expected: !` or `event not found`.
  2. zsh NOMATCH glob — Default zsh behavior treats `(...)` as KSH-style glob alternation grouping. When no files match, zsh aborts with `(eval):1: no matches found: (...)`.

The combination is high-likelihood when documentation prose contains addendum-marker references like `(IMP-5)`, `(CRIT-3)`, `(SUG-1)` near inline-code spans containing operators like `!`.

Real-world impact

Discovered during a project's `/compound` slash command (a /compound-engineering aggregate-knowledge command). One innocuous documentation rewrite added prose like `wrapped with `if !` to surface import failures loudly (IMP-5)` to the command file, and `/compound --aggregate` became completely unusable until the prose was rephrased. The command's actual logic was unchanged.

This is a slash-command authoring footgun: command authors think markdown inline-code spans are safe (they're standard markdown formatting for code references), but Claude Code's preprocessor doesn't fully implement markdown semantics and lets the syntax leak into shell evaluation.

Suggested fix

The preprocessor should treat markdown inline-code spans as terminal tokens — content between matched backtick pairs is opaque, content outside backticks is plain text. Neither should be eval-ed through zsh. If shell evaluation IS required (for variable substitution or similar), it should happen against explicitly-marked template substitution syntax, not implicitly via raw markdown.

Workaround in user-space

The author-side workaround is rephrasing prose to avoid `(...)` between two inline-code spans (e.g., `(IMP-5)` → `per IMP-5`). This works but is brittle — operators have to know about the trigger pattern, and any new operator typing slash-command arguments containing parens hits the same parser path.

Versions

  • Claude Code CLI: 2.1.126 (visible in jsonl session metadata)
  • Shell: zsh on macOS (default behavior with NOMATCH option set)
  • `CLAUDE_CODE_SHELL=bash` does NOT prevent this — escaping is upstream of shell selection

Related context

Companion class — the same upstream parser that escapes `!` to `!` causes a related failure surfaced earlier in the same codebase. Documented at the project level here: `CLAUDE.md` § "Shell Conventions for Bash Tool Calls" → "Third class".

extent analysis

TL;DR

The Claude Code slash-command preprocessor should be updated to treat markdown inline-code spans as opaque text, rather than evaluating the content between them as a zsh command-substitution span.

Guidance

  • Identify and rephrase markdown command files to avoid using parentheses between inline-code spans, as a temporary workaround.
  • Review the preprocessor code to ensure it correctly handles markdown inline-code spans and does not evaluate them as shell commands.
  • Consider implementing explicit template substitution syntax for shell evaluation, rather than relying on implicit markdown syntax.
  • Test the updated preprocessor with various markdown command files to ensure it correctly handles different scenarios.

Example

No code snippet is provided, as the issue is related to the preprocessor's parsing of markdown syntax, and a specific code example is not necessary to illustrate the problem.

Notes

The issue is specific to the Claude Code CLI version 2.1.126 and the zsh shell on macOS, but the suggested fix and workaround should be applicable to other versions and shells as well.

Recommendation

Apply the workaround of rephrasing markdown command files to avoid using parentheses between inline-code spans, until the preprocessor is updated to correctly handle markdown inline-code spans. This will prevent the evaluation of prose between inline-code spans as shell commands and avoid errors related to ! mangling and zsh NOMATCH glob behavior.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Markdown inline-code spans (`` `...` ``) should be treated as opaque text by the slash-command preprocessor, not as zsh command-substitution boundaries. The prose between two adjacent inline-code spans is plain markdown text and should NOT be eval-ed through any shell.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Slash-command preprocessor evaluates markdown inline-code-adjacent prose as zsh command substitution [1 comments, 2 participants]