Skip to content

KeyError: 'cost_usd' with Max subsription #2

Description

@kzmszk

I tried claude-code-sdk for python and the most basic sample didn't work properly.
I'm using claude code with Max subscription.
I think 'cost_usd' is used only with API_TOKEN users?

The env or errors are as follows:

$  uv pip list
Package           Version
----------------- -------
anyio             4.9.0
claude-code-sdk   0.0.10
idna              3.10
sniffio           1.3.1
typing-extensions 4.14.0
$ cat basic_sample.py
import anyio
from claude_code_sdk import query

async def main():
    async for message in query(prompt="What is 2 + 2?"):
        print(message)

anyio.run(main)

$ python basic_sample.py 
SystemMessage(subtype='init', data={'type': 'system', 'subtype': 'init', 'cwd': '/workspace/sdk', 'session_id': 'b2b8a840-a344-4761-8415-106d197d79db', 'tools': ['Task', 'Bash', 'Glob', 'Grep', 'LS', 'exit_plan_mode', 'Read', 'Edit', 'MultiEdit', 'Write', 'NotebookRead', 'NotebookEdit', 'WebFetch', 'TodoRead', 'TodoWrite', 'WebSearch'], 'mcp_servers': [], 'model': 'claude-sonnet-4-20250514', 'permissionMode': 'default', 'apiKeySource': 'none'})
AssistantMessage(content=[TextBlock(text='4')])
unhandled exception during asyncio.run() shutdown
task: <Task finished name='Task-4' coro=<<async_generator_athrow without __name__>()> exception=RuntimeError('Attempted to exit cancel scope in a different task than it was entered in')>
Traceback (most recent call last):
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/_internal/transport/subprocess_cli.py", line 193, in receive_messages
    yield data
GeneratorExit

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/_internal/transport/subprocess_cli.py", line 182, in receive_messages
    async with anyio.create_task_group() as tg:
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 778, in __aexit__
    if self.cancel_scope.__exit__(type(exc), exc, exc.__traceback__):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 457, in __exit__
    raise RuntimeError(
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in
Traceback (most recent call last):
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/_internal/client.py", line 38, in process_query
    message = self._parse_message(data)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/_internal/client.py", line 89, in _parse_message
    cost_usd=data["cost_usd"],
             ~~~~^^^^^^^^^^^^
KeyError: 'cost_usd'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/workspace/sdk/basic_sample.py", line 8, in <module>
    anyio.run(main)
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/anyio/_core/_eventloop.py", line 74, in run
    return async_backend.run(func, args, {}, backend_options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2310, in run
    return runner.run(wrapper())
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/node/.local/share/uv/python/cpython-3.12.11-linux-aarch64-gnu/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/node/.local/share/uv/python/cpython-3.12.11-linux-aarch64-gnu/lib/python3.12/asyncio/base_events.py", line 691, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2298, in wrapper
    return await func(*args)
           ^^^^^^^^^^^^^^^^^
  File "/workspace/sdk/basic_sample.py", line 5, in main
    async for message in query(prompt="What is 2 + 2?"):
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/__init__.py", line 101, in query
    async for message in client.process_query(prompt=prompt, options=options):
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/_internal/client.py", line 43, in process_query
    await transport.disconnect()
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/claude_code_sdk/_internal/transport/subprocess_cli.py", line 152, in disconnect
    await self._process.wait()
  File "/workspace/sdk/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1082, in wait
    return await self._process.wait()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/node/.local/share/uv/python/cpython-3.12.11-linux-aarch64-gnu/lib/python3.12/asyncio/subprocess.py", line 137, in wait
    return await self._transport._wait()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/node/.local/share/uv/python/cpython-3.12.11-linux-aarch64-gnu/lib/python3.12/asyncio/base_subprocess.py", line 230, in _wait
    return await waiter
           ^^^^^^^^^^^^
asyncio.exceptions.CancelledError: Cancelled by cancel scope ffff923b21b0
$  

Activity

  1. self-assigned this
    on Jun 13, 2025
  2. r488it commented on Jun 13, 2025

    @r488it
  3. couloirextreme commented on Jun 13, 2025

    @couloirextreme

    Having the same issue.

  4. oreoluwa-xyz commented on Jun 14, 2025

    @oreoluwa-xyz

    I am as well.

  5. bam4564 commented on Jun 14, 2025

    @bam4564

    Also facing this issue

  6. ali-coplanet commented on Jun 15, 2025

    @ali-coplanet

    same here

  7. lunartown commented on Jun 16, 2025

    @lunartown

    same here

  8. unclecode commented on Jun 17, 2025

    @unclecode

    CLI’s JSON schema changed, it no longer returns cost_usd, but the SDK still hard-codes that key inside _parse_message so the lookup bombs out, the exception cancels the AnyIO scope, and you see the CancelledError. I can make a PR propbably, but now very busy with Crawl4ai, so here is a zero-touch option plus a runtime shim:

    # hot-patch missing `cost_usd` key so _parse_message stops blowing up
    from types import MethodType
    from claude_code_sdk._internal.client import InternalClient as _IC
    
    _orig = _IC._parse_message
    def _shim(self, data):
        if data.get("type") == "result":
            # both old and new JSON formats now covered
            data.setdefault("cost_usd", data.get("cost", 0.0))
            data.setdefault("total_cost", data.get("total_cost_usd",
                                                   data.get("total_cost", data["cost_usd"])))
        return _orig(self, data)
    
    _IC._parse_message = MethodType(_shim, _IC)
    
    # Now use it, as it supposed to be
    import anyio
    from claude_code_sdk import query
    
    async def main():
        async for message in query(prompt="What is 2 + 2?"):
            print(message)
    
    anyio.run(main)
  9. unclecode commented on Jun 17, 2025

    @unclecode

    I've fixed this issue! Here's the PR: #14

    The fix handles the missing cost_usd field for Max subscription users by making it optional and using .get() with a default value.

    This should resolve the KeyError while maintaining backward compatibility.

  10. ltawfik commented on Jun 18, 2025

    @ltawfik
    Collaborator

    This is fixed with the latest SDK release, please pip install --upgrade claude-code-sdk, thanks everyone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions