[BUG] Inline !`cmd` preprocessor executes example commands inside fenced markdown code blocks (repro: /plugin-dev:command-development runs npm test)

Status Open
Reported on v2.1.234
Maintainer reply None cached
Activity 1 comment · opened Aug 18, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (open issues; see "Prior reports" below for closed ones)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

The inline-bash preprocessor that expands ` !cmd patterns in slash commands and skills does not respect markdown fencing. It scans the whole skill body, including fenced code blocks, and executes anything that matches. That means a skill whose job is to *document* the !cmd ` syntax has its documentation examples executed for real in the user's current working directory.

This is reproducible today with the first-party plugin-dev plugin from the claude-plugins-official marketplace. Invoking /plugin-dev:command-development in a project with no package.json runs npm test and surfaces a shell error, because the skill's SKILL.md contains an example command file inside a fenced ```markdown block.

The offending content is at skills/command-development/SKILL.md line 492, inside a fenced block that opens at line 484:

~~~

Testing Pattern

---
description: Run tests for specific file
argument-hint: [test-file]
allowed-tools: Bash(npm:*)
---

Run tests: !`npm test $1`

Analyze results and suggest fixes for failures.

~~~

The same example also appears at skills/command-development/examples/simple-commands.md line 100.

I want to be clear that I do not think the plugin content is wrong. The example is correctly fenced, which is exactly what a documentation author should do. The bug is that fencing does not suppress expansion. That is why I am filing here rather than against the plugins repo. The plugin is just the most convenient first-party repro.

The impact is broader than the noisy error. Any skill or command that documents the ! syntax will have its example commands executed in the user's project. Here it happened to be harmless (npm test with ENOENT). A documentation example showing ` !git clean -fdx , !rm -rf ./build , or a deploy command would not be harmless. Sixteen !... patterns exist in this one SKILL.md alone, several of which reference ${CLAUDE_PLUGIN_ROOT}` scripts.

What Should Happen?

` !cmd ` patterns that appear inside a fenced code block (and, I would argue, inside inline code spans) should be treated as literal text and not executed.

Failing that, at minimum a shell failure originating from a documentation-only skill should not surface to the user as an Error:.

Two possible fixes:

  1. Make the preprocessor markdown-aware: skip ! expansion inside fenced code blocks and inline code spans. This is the fix that makes correct documentation behave correctly, and needs no change to any existing skill.
  2. Provide an explicit escape syntax and update the plugin-dev skill docs to use it. This works but requires every skill author who documents the syntax to know about and apply the escape, and it leaves existing third-party skills broken.

Option 1 seems clearly preferable, since fencing is already the universal markdown convention for "this is a sample, not a directive".

Error Messages/Logs

Error: Shell command failed for pattern "!`npm test $1`": [stderr]
npm error code ENOENT
npm error syscall open
npm error path /home/<user>/<project>/package.json
npm error errno -2
npm error enoent Could not read package.json: Error: ENOENT: no such file or directory, open '/home/<user>/<project>/package.json'
npm error enoent This is related to npm not being able to find a file.

Steps to Reproduce

  1. Install the plugin-dev plugin from the claude-plugins-official marketplace via /plugin. (I reproduced this on a freshly updated copy, followed by /reload-plugins.)
  2. cd into any project that has no package.json at its root. A Python repo works fine. Any empty directory should also work.
  3. Start claude in that directory.
  4. Run the slash command /plugin-dev:command-development.
  5. The error above appears on stderr. npm test has been executed against the current working directory even though the command lives inside a fenced ```markdown block in the skill body.

To confirm the source, grep -n '!' ~/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/command-development/SKILL.md` lists 16 matches, all of which are inside fenced documentation examples.

I have only verified the plugin-dev path above. If you want a self-contained case, I would expect a local .claude/commands/demo.md containing a fenced ``markdown block whose body includes !echo EXECUTED to show the same thing when /demo` is run, but I have not confirmed that the local-command path and the plugin-skill path share the preprocessor.

Prior reports

This has been reported before and is still present in 2.1.234. Filing fresh per the auto-lock bot's instruction to open a new issue and reference the old one.

  • #12781 "Skill loading executes inline bash patterns from documentation examples" (closed as not planned, locked). Same root cause, and it also cites this same plugin-dev:command-development skill.
  • #39864 "feat: Skip dynamic context injection inside markdown code blocks in SKILL.md" (closed as a duplicate of #12781).
  • #55574 "Skill loader parses markdown content as shell commands" (closed).
  • #9643 "[FEATURE] Escape ! execution in slash commands" (closed as not planned). This is the option-2 fix above.

Claude Model

Not sure / Multiple models (the failure happens during command preprocessing, before the model is involved)

Is this a regression?

No, this never worked. #12781 dates to 2025-12-01 and describes identical behavior.

Claude Code Version

2.1.234 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

Plugin: plugin-dev from claude-plugins-official, authored by Anthropic. Installed at ~/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/. Updated and reloaded immediately before reproducing, so this is not a stale-cache artifact.

Affected files in that plugin, for reference:

  • skills/command-development/SKILL.md (16 patterns, notably line 492 ` !npm test $1 and line 525 !gh pr view $1 `)
  • skills/command-development/examples/simple-commands.md (line 100)

Note that line 525 is a gh pr view example, which would fire a network call and a gh auth path in any repo where the command is invoked. That one illustrates the side-effect concern better than the npm case does.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗