[BUG] Skill loader parses markdown content as shell commands — backtick-`!` still triggers bash history expansion (regression of #13655 / #28024 closed for inactivity, not fixed)
TL;DR
The skill loader still extracts text from inline-code spans in skill markdown bodies and passes it to bash permission checking, where the ! character triggers zsh/bash history expansion and the skill fails to load. This is the same bug as #13655 (closed 2026-03-08 for inactivity, not fixed) and #28024 (auto-closed as dup of #13655). Both have been auto-locked, so I'm filing a fresh issue per the bot's instructions.
Reproducing today, 2026-05-02, on the latest Claude Code stable.
Reproduction
A skill markdown file (~/git/individuals/nickmeinhold/claude-skills/consolidate.md) contains this bullet in body text — not in a fenced code block:
- **Length anomalies**: terse messages amid prose (`PR`, `yeah`, `ship !`) = high-conviction decisions; long messages amid terse = "I'm thinking out loud"
Invoking /consolidate causes the skill load to fail with:
Error: Shell command failed for pattern "!`) = high-conviction decisions; long messages amid terse = "I'm thinking out loud"
The error pattern is identical to the one techjoec reported on v2.1.37 in #13655 (Bash command failed for pattern "!\ triggers history expansion. Use \"). Same root cause: the ! between backticks in the markdown source gets pulled out and submitted to a shell where !-prefix is history expansion.
Fix on my side: removing the trailing ! from \ship !\` → \ship\. Skill loads. Confirms it's the backtick-!` pattern, not anything else in the line.
Why a new issue (and not reopening #13655)
- #13655 was closed 2026-03-08 by
github-actions[bot]with "Closing for now — inactive for too long. Please open a new issue if this is still relevant." It was then auto-locked 7 days later. So: explicit instruction in the closure to file a new one if still affected, and reopening isn't possible. - #28024 was auto-closed by the dedup bot 3 days after opening as a duplicate of #13655 — before any maintainer engagement.
Neither closure was on the merits. The bug was confirmed actively reproducing in v2.1.37 (techjoec's test matrix in #13655 is clean isolation evidence) and is still reproducing as of 2026-05-02.
Test matrix evidence (from #13655, confirmed independently still applies)
techjoec tested all common shell metacharacters in backticks; only ! triggers the bug:
| Pattern | Triggers bug? |
|---|---|
| ` echo hello , foo_bar , code | No |
| \$HOME , \$(whoami) , \$ | No |
| echo hello; echo world , ; | No |
| home/user\file , \ , \n | No |
| cat file \| grep foo , \| | No |
| ! ` | Yes |
This isolates the bug specifically to bash/zsh history expansion, not to general shell-metacharacter handling.
Suggested root cause
The skill loader appears to be:
- Extracting text between backticks from skill markdown body content
- Passing that text into a shell-aware permission check
- The shell evaluates
!-prefixed text via history expansion before any permission logic runs - Skill load aborts with the expansion error
The fix surface is in step 2 — skill markdown content should never be evaluated by a shell. Permission checking on extracted code-span content (if needed at all) should treat the content as a literal string, not parse it through a shell.
Adjacent open issues that are likely the same family of "skill content unsafely passed to shell":
- #52226 — "Skills: no escape syntax for literal
\$<digit>in command bodies" - #49828 — "Embedded commands (\
!\cmd\\) in skill/command markdown silently fail in CI environment" - #54356 — "skill !-context bash failing 'Contains expansion'"
- #37504 (closed) — "Skill loading evaluates file content against bash permission patterns"
- #31201 (closed) — "Skill markdown content triggers Bash permission pre-check incorrectly"
- #39864 (closed) — "Skip dynamic context injection inside markdown code blocks in SKILL.md"
The pattern across all of these: skill markdown content surfaces to shell-evaluation contexts in ways the markdown author shouldn't have to think about. The right fix is structural — strict separation of skill content from shell evaluation — not pattern-by-pattern escaping.
Workaround
For affected skill authors: avoid ! inside backtick-wrapped inline code in skill body text. Use one of:
- Plain text without backticks:
(PR, yeah, ship !) - Move the
!outside the backticks:\ship\! - Remove the
!entirely if the example doesn't strictly need it
Request
Please don't auto-close this for inactivity. The bug has been around for 3+ months across at least two reports; a third closure for the same reason would be the system tracker swallowing valid bug reports.
🤖 Generated with Claude Code
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗