[BUG] Skill loader parses markdown content as shell commands — backtick-`!` still triggers bash history expansion (regression of #13655 / #28024 closed for inactivity, not fixed)

Resolved 💬 1 comment Opened May 2, 2026 by nickmeinhold Closed May 4, 2026

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:

  1. Extracting text between backticks from skill markdown body content
  2. Passing that text into a shell-aware permission check
  3. The shell evaluates !-prefixed text via history expansion before any permission logic runs
  4. 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

View original on GitHub ↗

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