Skip to content

Conversation

@stephaniepang97
Copy link

Problem

When using programmatic tool calling (PTC) with tool_runner, the API returns a container_id in the response that must be passed in subsequent requests. Without this, the API returns:

container_id is required when there are pending tool uses generated by code execution with tools.

Solution

Update both sync and async tool runners to extract message.container.id from responses and set it in self._params["container"] for subsequent API calls.

Changes

  • BaseSyncToolRunner.__run__(): Added container propagation after getting message
  • BaseAsyncToolRunner.__run__(): Added container propagation after getting message (async version)

Testing

This enables using tool_runner with programmatic tool calling where client-side tools are called from within code execution. The container lifecycle is now properly managed across requests.

Example

runner = client.beta.messages.tool_runner(
    model="claude-sonnet-4-5",
    tools=[
        {"type": "code_execution_20250825", "name": "code_execution"},
        {
            "name": "my_tool",
            "description": "...",
            "input_schema": {...},
            "allowed_callers": ["code_execution_20250825"]
        }
    ],
    messages=[...],
    betas=["advanced-tool-use-2025-11-20"],
)

for message in runner:
    # Now works! Container ID is automatically propagated between requests
    print(message)

When using programmatic tool calling (PTC), the API returns a container_id
in the response that must be passed in subsequent requests. Without this,
the API returns an error:
'container_id is required when there are pending tool uses generated by
code execution with tools.'

This change updates both sync and async tool runners to extract the
container.id from responses and pass it in subsequent API calls.
@stephaniepang97 stephaniepang97 requested a review from a team as a code owner January 24, 2026 05:36
@benkomalo benkomalo requested a review from henrykeetay January 25, 2026 16:47
Copy link
Collaborator

@dtmeadows dtmeadows left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me and the reasoning makes sense. @karpetrosyan can I leave the final review to you? If it's helpful here's the specific place in the docs about having to pass this: https://platform.claude.com/docs/en/agents-and-tools/tool-use/programmatic-tool-calling#step-3-provide-tool-result

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants