claude-code - 💡(How to fix) Fix [BUG] Skill tool's args parameter drops the first token before $1/$2 substitution

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When invoking a skill via the Skill tool with args="<token1> <token2>", the runtime strips the first whitespace-separated token before substituting $1/$2 positional placeholders in the skill file body. The same skill, invoked via a typed slash command, substitutes correctly.

Root Cause

Root cause hypothesis

Fix Action

Fix / Workaround

Workarounds

Skills are presented as a stable interface for invoking long workflows. When a model that learns the skill via documentation tries to use it programmatically, the documented $1/$2 substitution doesn't behave as the docs describe — it silently mis-substitutes, then fails at the precondition check downstream. This makes skills with required ticket-key / hours / slug arguments effectively unusable from the model's perspective without a per-invocation manual workaround.

Code Example

---
name: ship-feature
description: ...
---

# ship-feature

**Arguments:**
- `$1`Jira ticket key, e.g. `LP-5539`. Required.
- `$2` — worklog hours, e.g. `2h`, `30m`. Optional, default `1h`.

## Preconditions

1. Current branch name contains the ticket key (grep for `$1` in `git branch --show-current`).
...

---

{ "skill": "ship-feature", "args": "LP-5684 1h" }

---

/ship-feature LP-5684 1h

---

**Arguments:**
- `1h`Jira ticket key, e.g. `LP-5539`. Required.
- `` — worklog hours, e.g. `2h`, `30m`. Optional, default `1h`.
RAW_BUFFERClick to expand / collapse

[BUG] Skill tool's args parameter drops the first token before $1/$2 substitution

Summary

When invoking a skill via the Skill tool with args="<token1> <token2>", the runtime strips the first whitespace-separated token before substituting $1/$2 positional placeholders in the skill file body. The same skill, invoked via a typed slash command, substitutes correctly.

Environment

  • Claude Code platform: win32 (Windows)
  • Skills involved: user-level skills at ~/.claude/skills/<name>/SKILL.md
  • Skill files use the documented $1, $2 positional placeholder syntax (per the Skills docs and the inline **Arguments:** convention).

Reproduction

Skill file (~/.claude/skills/ship-feature/SKILL.md):

---
name: ship-feature
description: ...
---

# ship-feature

**Arguments:**
- `$1` — Jira ticket key, e.g. `LP-5539`. Required.
- `$2` — worklog hours, e.g. `2h`, `30m`. Optional, default `1h`.

## Preconditions

1. Current branch name contains the ticket key (grep for `$1` in `git branch --show-current`).
...

Programmatic invocation (broken):

The model invokes:

{ "skill": "ship-feature", "args": "LP-5684 1h" }

The skill body is rendered with:

  • $1"1h" ❌ (should be "LP-5684")
  • $2"" ❌ (should be "1h")

The first token (LP-5684) is silently dropped before substitution. Skill execution then aborts at the precondition check ("$1 doesn't match the Jira key shape [A-Z]+-\d+").

User-typed slash invocation (correct):

User types in chat:

/ship-feature LP-5684 1h

The skill body is rendered with:

  • $1"LP-5684"
  • $2"1h"

Skill executes correctly.

Confirmed cases (twice in one session, 2026-05-07)

  1. Skill(skill="start-jira", args="LP-5684 wizard-nav-and-mappings-iam") rendered with $1 = "wizard-nav-and-mappings-iam", $2 = "".
  2. Skill(skill="ship-feature", args="LP-5684 1h") rendered with $1 = "1h", $2 = "".

In both cases the rendered skill body's **Arguments:** section showed the wrong-token mapping in the substituted text, e.g.:

**Arguments:**
- `1h` — Jira ticket key, e.g. `LP-5539`. Required.
- `` — worklog hours, e.g. `2h`, `30m`. Optional, default `1h`.

Root cause hypothesis

The slash-command path (/ship-feature LP-5684 1h) feeds raw "ship-feature LP-5684 1h" into a parser that strips the leading skill-name word before splitting positional args. The Skill-tool path appears to share the same parser, but args is provided without the leading skill name (it's already specified separately via the skill parameter). The parser still strips the leading word, so the user's first real argument disappears.

Workarounds

  1. Prepend a dummy first token when invoking programmatically: Skill(skill="ship-feature", args="x LP-5684 1h"). The x gets eaten, real args land in their slots. Hacky.
  2. Bypass the Skill tool entirely and execute the workflow steps with direct tool calls.
  3. Have the user type the slash command in chat — the slash-command path is unaffected.

Why it matters

Skills are presented as a stable interface for invoking long workflows. When a model that learns the skill via documentation tries to use it programmatically, the documented $1/$2 substitution doesn't behave as the docs describe — it silently mis-substitutes, then fails at the precondition check downstream. This makes skills with required ticket-key / hours / slug arguments effectively unusable from the model's perspective without a per-invocation manual workaround.

Related

  • #18044 — "[BUG] Skill tool $ARGUMENTS variable not populated when invoking skills with command blocks". Sibling bug in the same arg-handling area. That one zeroes out the full-string variable; this one shifts the positional ones by one.
  • #54535 — "Skill tool feedback loop". Notes that some Skill-tool behaviors only fire on user-typed slash invocations, not programmatic ones — same general theme of the two paths diverging.

Suggested fix direction

Either: (a) the slash-command parser should strip the leading skill-name before delegating to the shared arg-substitution function, so args arrives at substitution stripped of the command word; or (b) the Skill-tool entry should not re-invoke the strip step since skill is already separated. Without seeing the runtime, my guess is (b) is the cleaner fix.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Skill tool's args parameter drops the first token before $1/$2 substitution