Skill tool: multi-word args cause $N positional substitution to corrupt literal $N tokens in skill body (e.g. Excel cell refs)

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 16, 2026

Description

When invoking a Skill via the Skill tool with a multi-word args string, the returned skill content can be corrupted: literal $N tokens inside the skill's Markdown body (e.g. Excel-style absolute cell references like $B$2) get replaced with words from the args string, as if the harness were doing shell-style positional-parameter substitution ($1, $2, ...) against the whole skill body using the invocation args as the positional-parameter list.

This looks like the same templating mechanism used for slash-command files (which support $ARGUMENTS, $1, $2, ... placeholders) is being applied to Skill content as well, where it was never intended to run — Skill bodies are plain documentation/instructions, not command templates, and can legitimately contain literal $N sequences (spreadsheet cell references being the clearest example).

Steps to reproduce

  1. Install the official xlsx skill (from anthropics/skills, skills/xlsx/SKILL.md) under ~/.claude/skills/xlsx/SKILL.md. Its body contains literal Excel references such as ` $B$2 , $B$5 , $B$6 `.
  2. Invoke it with a multi-word args string, e.g.:

``
Skill({ skill: "xlsx", args: "smoke test: confirm skill loads cleanly, no action needed" })
``

  1. Observe the returned skill content.

Expected

The skill body is returned byte-for-byte as written in SKILL.md.

Actual

Several $N tokens in the body are replaced with words from args, e.g. (own reproduction):

  • ` $B$2 $Bconfirm `
  • ` $B$5 $Bcleanly, `
  • ` $B$6 $Bno `

The substitution appears to be positional: args split on whitespace, 0-indexed, and $N in the body replaced with args_words[N]. For the args string "smoke test: confirm skill loads cleanly, no action needed" (0=smoke, 1=test:, 2=confirm, 3=skill, 4=loads, 5=cleanly,, 6=no, ...), $2confirm, $5cleanly,, $6no all match exactly.

Verified NOT a file corruption

Re-reading the on-disk SKILL.md file directly afterward shows it is byte-for-byte correct ($B$2 etc. intact). The corruption only appears in what the Skill tool returns/renders for that turn — so this is a rendering/templating bug in the Skill invocation path, not a persistence bug.

Suggested fix

Don't apply $1/$2/$ARGUMENTS-style positional substitution to Skill body content — that behavior belongs to slash-command templates only. If Skill invocations are meant to support argument templating in the future, it should require an explicit opt-in marker in the SKILL.md rather than blindly matching any literal $N substring.

Environment

  • Windows 11 Pro, PowerShell 5.1 primary shell, Git Bash also available
  • Reproduced via Claude Code CLI

View original on GitHub ↗