plugin-dev: command-development teaches `$1` as the first argument, but `$N` is 0-based

Author: errmakovCreated Sep 17, 2026Updated Sep 17, 2026

What's wrong

plugins/plugin-dev/skills/command-development/SKILL.md says "Capture individual arguments with $1, $2, $3, etc." and uses $1 as the first argument throughout. In Claude Code, $N is 0-based shorthand for $ARGUMENTS[N]: $0 is the first argument and $1 the second. That applies to commands/*.md files as well as skills.

The guide's own examples, run as written on Claude Code 2.1.273 (commands in .claude/commands/, request captured with a local stub):

Guide example Guide says it expands to Claude received
/review-pr 123 high alice Review pull request #123 with priority level high. / After review, assign to alice for follow-up. Review pull request #high with priority level alice. / After review, assign to $3 for follow-up.
/deploy api staging --force --skip-tests Deploy api to staging environment with options: --force --skip-tests Deploy staging to --force environment with options: --skip-tests

The second example is also wrong about $3: an indexed placeholder takes one argument, not "remaining arguments".

Since plugin-dev is what people (and Claude) use to write commands, the mistake spreads: code-modernization read every argument one position off, which #6153 fixes for that plugin only.

Where it appears

In command-development/SKILL.md:

  • "Using Positional Arguments" and "Combining Arguments" (the two examples above)
  • "Argument Handling", whose $IF($1, …) example also uses a construct that isn't in the Claude Code docs
  • The file-reference, testing, documentation, workflow, plugin-pattern, integration and validation examples, such as @$1, npm test $1, gh pr view $1 and Deploy to $1
  • Troubleshooting: "Verify $1, $2 syntax correct"

The copy in anthropics/claude-code/plugins/plugin-dev has the same text.

Suggested fix

Rewrite the positional examples to use named arguments, the way #6153 does for code-modernization, e.g.:

markdown
---
description: Review PR with priority and assignee
argument-hint: [pr-number] [priority] [assignee]
arguments: [pr, priority, assignee]
---

Review pull request #$pr with priority level $priority.
After review, assign to $assignee for follow-up.

On 2.1.273, /review-pr 123 high alice with this file expands to Review pull request #123 with priority level high. and After review, assign to alice for follow-up.

Where indexed access is shown, use $0, $1, $2 (or $ARGUMENTS[0] and so on) with a note that numbering starts at 0, and that \$1 keeps a literal $1 for awk or shell snippets in a command body.

Related

  • Same class of problem in a shipped command: plugins/commit-commands/commands/clean_gone.md has awk '{print $1}' in its body. It's harmless when /clean_gone runs with no arguments or one word, but two or more words turn it into awk '{print <second word>}'. Escaping it as \$1 would make it robust.
  • anthropics/claude-code#94709 and #94496: users hit by the same substitution in their own skills.

Source: anthropics/claude-plugins-official