📝

【Claude Codeチャレンジ日誌3】SDK使用時にKeyError: 'cost_usd'が発生

に公開

はじめに

Claude Code SDKを使ってPythonからClaude AIと対話しようとしたら、突然このようなエラーに遭遇しました:

KeyError: 'cost_usd'

この記事では、このエラーの原因と解決方法について、実際の修正手順を含めて詳しく解説します。

問題の背景

エラーの詳細

Claude Code SDK(バージョン0.0.10)を使用して簡単なコードを実行すると:

import anyio
from claude_code_sdk import query

async def test():
    async for message in query(prompt="Hello, Claude!"):
        print(message)

anyio.run(test)

以下のようなエラーが発生:

Traceback (most recent call last):
  File ".../claude_code_sdk/_internal/client.py", line 38, in process_query
    message = self._parse_message(data)
  File ".../claude_code_sdk/_internal/client.py", line 89, in _parse_message
    cost_usd=data["cost_usd"],
             ~~~~^^^^^^^^^^^^
KeyError: 'cost_usd'

原因

このエラーは、Anthropicの Max subscription プランのユーザーに発生します。

  • 通常プラン: APIレスポンスにcost_usd(料金情報)が含まれる
  • Max subscription: 料金情報が含まれない(定額制のため)

SDKは全てのユーザーに対してcost_usdフィールドが存在すると仮定していたため、Max subscriptionユーザーでエラーが発生していました。

解決方法

方法1: Claude Codeに修正を依頼する(推奨)

Claude Codeに以下のような修正依頼を出すと、自動的に修正してくれます:

Claude Code SDKでKeyError: 'cost_usd'エラーが出ています。
Max subscriptionユーザーなので、cost_usdフィールドが返されないようです。
このエラーを修正してください。

エラー箇所:
- claude_code_sdk/_internal/client.py の89行目
- ResultMessageクラスのcost_usdフィールド

方法2: 手動で修正する

1. client.pyの修正

仮想環境内のclaude_code_sdk/_internal/client.pyを編集:

# 修正前(89行目付近)
cost_usd=data["cost_usd"],

# 修正後
cost_usd=data.get("cost_usd"),

同様にtotal_costも修正:

# 修正前
total_cost_usd=data["total_cost"],

# 修正後
total_cost_usd=data.get("total_cost"),

2. types.pyの修正

claude_code_sdk/types.pyResultMessageクラスを編集:

# 修正前
@dataclass
class ResultMessage:
    """Result message with cost and usage information."""
    
    subtype: str
    cost_usd: float
    duration_ms: int
    duration_api_ms: int
    is_error: bool
    num_turns: int
    session_id: str
    total_cost_usd: float
    usage: dict[str, Any] | None = None
    result: str | None = None

# 修正後
@dataclass
class ResultMessage:
    """Result message with cost and usage information."""
    
    subtype: str
    cost_usd: float | None  # Noneを許可
    duration_ms: int
    duration_api_ms: int
    is_error: bool
    num_turns: int
    session_id: str
    total_cost_usd: float | None  # Noneを許可
    usage: dict[str, Any] | None = None
    result: str | None = None

方法3: 最新版のインストール(将来的に)

GitHubの最新版には修正が含まれている可能性があります:

pip install git+https://github.com/anthropics/claude-code-sdk-python.git

修正後の動作確認

修正後、同じコードを実行すると正常に動作します:

# 実行結果
受信: SystemMessage
受信: AssistantMessage
受信: ResultMessage

最終的な応答: ResultMessage(
    subtype='success', 
    cost_usd=None,  # Noneで正常に処理される
    duration_ms=3895, 
    is_error=False, 
    num_turns=1, 
    result='Hello! I'm ready to help...'
)

cost_usd=Noneとなっていることに注目してください。エラーではなく、正常にNoneとして処理されています。

まとめ

ポイント

  1. Max subscriptionユーザーは料金情報が返されない
  2. SDKが料金情報を必須と仮定していたためエラーが発生
  3. .get()メソッドを使用してオプショナルフィールドとして扱うことで解決

学び

  • APIレスポンスの構造は、ユーザーのプランによって異なることがある
  • 外部APIを扱う際は、オプショナルなフィールドを適切に処理することが重要
  • 型定義では| Noneを使用してオプショナルな値を明示的に示すべき

関連リンク

この修正により、Max subscriptionユーザーでもClaude Code SDKを問題なく使用できるようになります。同じエラーに遭遇した方の参考になれば幸いです!

Accenture Japan (有志)

Discussion