📝

Claude Code CLIで躓いた話:位置引数とオプションの勘違い

に公開

問題と解決策

問題

claude -p 'test' は動作するが、claude -p '-test' でエラーが発生する

# 正常に動作
claude -p 'test' 

# エラーになる
claude -p '-test'
# error: unknown option '-test'

解決策

答え: 常に -- を使用する

# コマンドライン
claude -p -- "プロンプト"

# Node.js
spawn('claude', ['-p', '--', prompt])

これで - で始まるプロンプトでも安全に処理できます。

なぜこの問題に気づくのが遅れたのか

1. 偶然動作していた

claude -p 'test' は正常に動作していたため、仕様を正しく理解していると思い込んでいました。実際は偶然動いていただけでした。

2. プログラムからの呼び出しで発覚

問題が顕在化したのは、Node.js から Claude CLI を呼び出していた時でした:

// 問題のあったコード
const claudeProcess = spawn('claude', ['-p', prompt]);

prompt- で始まるマークダウンリスト(- タスク1: ...)だった時にエラーが発生しました。

3. 原因の特定に時間がかかった理由

  1. プログラム側の問題だと思い込んだ: Node.js の spawn や引数処理に問題があると疑った
  2. Claude CLI の仕様を確認しなかった: claude --help を最初に見ていれば早期発見できた
  3. コマンドライン直接実行でのテストを怠った: プログラム経由でしかテストしていなかった

Claude CLI の仕様

claude --help で確認できる正しい仕様:

Usage: claude [OPTIONS] [PROMPT]

Arguments:
  prompt                           Your prompt

Options:
  -p, --print                      Print mode

重要なポイント:

  • -p はオプションフラグ(引数なし)
  • PROMPT は別の位置引数
  • 両方を組み合わせ可能

エラーの原因

claude -p '-test' でエラーになる理由:

  1. Claude CLI の引数パーサーが -p をプリントモードフラグとして認識
  2. 次の -test を別のオプションとして解析しようとする
  3. -test は定義されていないオプションなのでエラー

プログラムからの正しい呼び出し方法

問題のコード

// 問題のあったコード
const claudeProcess = spawn('claude', ['-p', prompt]);

正しいコード

// 正解: 常に -- を使用
const claudeProcess = spawn('claude', ['-p', '--', prompt]);

応用例

標準入力との組み合わせ

Claude CLI は標準入力とプロンプトを同時に使えます:

# ファイル分析
cat server.log | claude -p -- "エラーパターンを分析して"

# コードレビュー  
cat script.py | claude -p -- "セキュリティ問題をチェックして"

Markdownファイルの注意点

Markdownプロンプトでは特に -- が重要です:

# 危険: エラーになる可能性
claude -p "$(cat prompt.md)"  # - から始まる行があるとエラー

# 安全: -- を使用
claude -p -- "$(cat prompt.md)"

# より安全: 標準入力を使用  
cat prompt.md | claude -p

まとめ

解決策(最重要)

# 常に -- を使用する
claude -p -- "プロンプト"
spawn('claude', ['-p', '--', prompt])

学んだ教訓

  1. 外部コマンドの問題は直接実行でまずテスト
  2. helpコマンドで仕様を最初に確認
  3. プログラム側の問題と決めつけない

他の人も陥りやすい理由

  • claude -p 'test' が偶然動作してしまう
  • プログラムから呼び出すと原因特定が困難
  • Markdownプロンプト(- で始まる行)で問題が顕在化

推奨パターン: 常に claude -p -- "$prompt" を使用

Discussion