feat: Skip dynamic context injection inside markdown code blocks in SKILL.md
Summary
The Dynamic Context Injection syntax (! + backtick-wrapped command) in SKILL.md is executed even when it appears inside markdown code blocks (triple backticks). This makes it impossible to document or show examples of the syntax within a SKILL.md file.
Reproduction
- Create a personal skill:
~/.claude/skills/my-skill/SKILL.md - Include the dynamic injection syntax as an example inside a code block:
~~~markdown
---
name: my-skill
description: Example skill
---
Dynamic Context Injection Examples
Below are examples of the dynamic injection syntax:
\\\`markdown
- Diff: !
gh pr diff - Changed files: !
gh pr diff --name-only
\\\`
~~~
- Invoke
/my-skill
Expected: Syntax inside code blocks is treated as documentation/examples and not executed.
Actual: The preprocessor executes the syntax even inside code blocks, causing a shell error:
Shell command failed for pattern "!`command`": [stderr]
(eval):1: redirection with no command
Why This Matters
- Skill authors cannot document advanced features. There is currently no way to show examples of Dynamic Context Injection or String Substitution (
$ARGUMENTS,${CLAUDE_SKILL_DIR}) syntax within a SKILL.md. Code blocks — the standard markdown convention for showing syntax examples — are not treated as safe zones.
- Prevents accidental command execution. Code blocks are universally understood as inert documentation. Users reasonably expect that placing shell commands inside triple backticks will not execute them. The current behavior violates this expectation and can lead to unintended side effects.
- Improves the official skill-creator plugin. The
skill-creatorplugin's own SKILL.md currently omits documentation for Dynamic Context Injection entirely — likely because including examples would trigger this exact issue. Fixing this would allow the official tooling to be more complete.
- Reduces debugging time. The current error message (
Shell command failed for pattern "!command") gives no indication of which file or line caused the failure. Adding file path and line number to the error would turn a multi-hour investigation into a one-minute fix.
Context
I discovered this while customizing the skill-creator plugin's SKILL.md to document the Dynamic Context Injection feature. I placed examples inside markdown code blocks, but the preprocessor scanned through code blocks and attempted to execute them as real shell commands.
Additionally, String Substitution variables ($ARGUMENTS, ${CLAUDE_SKILL_DIR}) are also substituted inside code blocks. When trying to document these variables as examples, they get replaced with actual values, making it impossible to show the intended content.
Suggested Improvements
1. Skip preprocessing inside code blocks (primary)
Exclude Dynamic Context Injection syntax and variable substitution inside markdown code blocks (` ` `).
This would allow skill authors to document and demonstrate these features within their SKILL.md files.
2. Provide an escape mechanism (secondary)
Offer a way to disable the syntax outside of code blocks as well. For example: \! + backtick-command could be treated as literal text.
3. Improve error messages (secondary)
Current error message:
Shell command failed for pattern "!`command`": [stderr]
(eval):1: redirection with no command
Suggested improvement:
Shell command failed in /Users/me/.claude/skills/my-skill/SKILL.md:15
Pattern: !`gh pr diff`
Error: (eval):1: redirection with no command
Including the file path and line number would make debugging significantly easier.
Environment
- macOS (Darwin 25.3.0)
- Shell: zsh
- Claude Code CLI
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗