Skill tool silently substitutes $N-style tokens in skill body from invocation args
What happened: Invoked a skill (via the Skill tool) with args: "scan jons/ONS_0??.md and report which files have findings". The returned skill body text had two legitimate awk field references, $2 and $0, silently replaced with literal words from the args string: substr($2,3) became substr(and,3) — and is the whitespace-split word at 0-indexed position 2 in the args — and substr($0,5) became substr(scan,5) — scan is the word at position 0. Every other line of the same SKILL.md file was unchanged (verified against a direct file read moments earlier in the same session).
Repro:
- Write a
SKILL.mdwhose body contains a code block using awk with$0/$1/$2etc. field references (e.g.awk '/pat/ {f=substr($2,3)}'). - Invoke the skill with an
argsstring whose whitespace-split words happen to occupy the same 0-indexed positions as the$Ntokens in the body. - The skill body returned to the model has those
$Nsubstrings replaced with the corresponding word fromargs.
Suspected cause: The skill-loading/templating step appears to treat any $N substring in the skill body as a positional-parameter placeholder to be filled from the whitespace-split invocation args, without checking whether the surrounding context (e.g. an awk script) intends $N to mean something else entirely.
Impact: Beyond corrupting displayed documentation/examples, this is a content-integrity issue and a potential injection vector — if a skill body's $N pattern gets substituted with args text that later gets executed or trusted, that's a real problem, not just a cosmetic one.
Evidence: Affected skill file: .claude/skills/restore-headings/SKILL.md, "Auditing a fix" section, awk snippet (git diff <before> -- jons/ | awk '/^\+\+\+ b\// {f=substr($2,3)} ...').
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗