litellm - 💡(How to fix) Fix [Bug]: anthropic_messages logging silently drops spend_logs rows for cross-route to OpenAI Responses backend

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Task-333 ... exception=Exception('[Non-Blocking] LiteLLM.Success_Call Error:
  1 validation error for AnthropicResponse
  Input should be a valid dictionary or instance of AnthropicResponse
  [type=model_type, input_value=ResponseCompletedEvent(...), input_type=ResponseCompletedEvent]
  For further information visit https://errors.pydantic.dev/2.12/v/model_type')

File ".../litellm/litellm_core_utils/litellm_logging.py", line 3458,
  in _handle_anthropic_messages_response_logging
    pydantic_result = AnthropicResponse.model_validate(result)
File ".../pydantic/main.py", line 716, in model_validate
pydantic_core._pydantic_core.ValidationError: 1 validation error for AnthropicResponse
  Input should be a valid dictionary or instance of AnthropicResponse
  [type=model_type, input_value=ResponseCompletedEvent(...), input_type=ResponseCompletedEvent]

During handling of the above exception, another exception occurred:

File ".../litellm/litellm_core_utils/litellm_logging.py", line 2542, in async_success_handler
    start_time, end_time, result = self._success_handler_helper_fn(...)
File ".../litellm/litellm_core_utils/litellm_logging.py", line 1917, in _success_handler_helper_fn
    raise Exception(f"[Non-Blocking] LiteLLM.Success_Call Error: {str(e)}")

Code Example

Task-333 ... exception=Exception('[Non-Blocking] LiteLLM.Success_Call Error:
  1 validation error for AnthropicResponse
  Input should be a valid dictionary or instance of AnthropicResponse
  [type=model_type, input_value=ResponseCompletedEvent(...), input_type=ResponseCompletedEvent]
  For further information visit https://errors.pydantic.dev/2.12/v/model_type')

File ".../litellm/litellm_core_utils/litellm_logging.py", line 3458,
  in _handle_anthropic_messages_response_logging
    pydantic_result = AnthropicResponse.model_validate(result)
File ".../pydantic/main.py", line 716, in model_validate
pydantic_core._pydantic_core.ValidationError: 1 validation error for AnthropicResponse
  Input should be a valid dictionary or instance of AnthropicResponse
  [type=model_type, input_value=ResponseCompletedEvent(...), input_type=ResponseCompletedEvent]

During handling of the above exception, another exception occurred:

File ".../litellm/litellm_core_utils/litellm_logging.py", line 2542, in async_success_handler
    start_time, end_time, result = self._success_handler_helper_fn(...)
File ".../litellm/litellm_core_utils/litellm_logging.py", line 1917, in _success_handler_helper_fn
    raise Exception(f"[Non-Blocking] LiteLLM.Success_Call Error: {str(e)}")

---

pydantic_result = AnthropicResponse.model_validate(result)

---

- model_name: my-local
     litellm_params:
       model: openai/my-local
       api_base: http://<host>:11434/v1
       api_key: dummy

---

curl -sS -X POST -H 'content-type: application/json' \
     -H "Authorization: Bearer <key>" \
     "http://<litellm>:4000/v1/messages?beta=true" \
     -d '{"model":"my-local","stream":true,"max_tokens":100,
          "messages":[{"role":"user","content":"hi"}]}'
RAW_BUFFERClick to expand / collapse

What happened?

When LiteLLM routes POST /v1/messages (or /v1/messages?beta=true) to a backend that returns OpenAI Responses API stream events instead of native Anthropic shape, the success handler crashes during spend_logs serialization. The crash is caught as "Non-Blocking" in async_success_handler, so the request to the client succeeds normally — but the request never lands in LiteLLM_SpendLogs, and the proxy UI shows no row for it.

This silently breaks observability for any cross-route setup where /v1/messages is configured to flow through the Responses API bridge (e.g. to a local Ollama backend that exposes /v1/responses). The user-visible response is fine — AnthropicResponsesStreamWrapper.async_anthropic_sse_wrapper correctly translates events back to anthropic-shape SSE — only the logging path is broken.

What's happening (trace)

  1. Client (claude-cli 2.1.148 in our case) sends POST /v1/messages?beta=true with anthropic-shape body.
  2. model_list routes to e.g. openai/<name> with api_base pointing at an OpenAI-Responses-compatible backend.
  3. LiteLLM activates the Responses API bridge — outgoing request is POST <api_base>/responses with body shape {model, input, instructions, tools}.
  4. Backend streams back OpenAI Responses API events: response.created, response.in_progress, response.output_item.added, …, response.completed.
  5. AnthropicResponsesStreamWrapper.async_anthropic_sse_wrapper translates events back to anthropic-shape SSE for the client — OK, user gets a normal response.
  6. In parallel, async_success_handler reaches _handle_anthropic_messages_response_logging(result=result) where result is a raw ResponseCompletedEvent (OpenAI SDK Responses type).
  7. AnthropicResponse.model_validate(result) raises ValidationError.
  8. The exception is wrapped by _success_handler_helper_fn as "Non-Blocking", so the client never sees it — but spend_logs gets nothing and the UI row is missing.

Stack trace

Task-333 ... exception=Exception('[Non-Blocking] LiteLLM.Success_Call Error:
  1 validation error for AnthropicResponse
  Input should be a valid dictionary or instance of AnthropicResponse
  [type=model_type, input_value=ResponseCompletedEvent(...), input_type=ResponseCompletedEvent]
  For further information visit https://errors.pydantic.dev/2.12/v/model_type')

File ".../litellm/litellm_core_utils/litellm_logging.py", line 3458,
  in _handle_anthropic_messages_response_logging
    pydantic_result = AnthropicResponse.model_validate(result)
File ".../pydantic/main.py", line 716, in model_validate
pydantic_core._pydantic_core.ValidationError: 1 validation error for AnthropicResponse
  Input should be a valid dictionary or instance of AnthropicResponse
  [type=model_type, input_value=ResponseCompletedEvent(...), input_type=ResponseCompletedEvent]

During handling of the above exception, another exception occurred:

File ".../litellm/litellm_core_utils/litellm_logging.py", line 2542, in async_success_handler
    start_time, end_time, result = self._success_handler_helper_fn(...)
File ".../litellm/litellm_core_utils/litellm_logging.py", line 1917, in _success_handler_helper_fn
    raise Exception(f"[Non-Blocking] LiteLLM.Success_Call Error: {str(e)}")

Relevant code

litellm/litellm_core_utils/litellm_logging.py:3458:

pydantic_result = AnthropicResponse.model_validate(result)

result is the raw stream event yielded by the Responses API backend — not the post-translation anthropic-shape object the client receives.

Reproduction

  1. LiteLLM 1.85.0 (ghcr.io/berriai/litellm-non_root:main-stable).
  2. model_list entry routing through the Responses API bridge:
    - model_name: my-local
      litellm_params:
        model: openai/my-local
        api_base: http://<host>:11434/v1
        api_key: dummy
  3. general_settings.store_prompts_in_spend_logs: true (so we'd otherwise expect to see UI rows).
  4. Hit /v1/messages?beta=true with anthropic-shape body and stream: true:
    curl -sS -X POST -H 'content-type: application/json' \
      -H "Authorization: Bearer <key>" \
      "http://<litellm>:4000/v1/messages?beta=true" \
      -d '{"model":"my-local","stream":true,"max_tokens":100,
           "messages":[{"role":"user","content":"hi"}]}'
  5. Observe: streaming response succeeds, container logs show the stack trace above, LiteLLM UI's Logs tab has no row.

Contrast that works

The same proxy with the same flag enabled, hitting /v1/messages for an Anthropic-backed model (e.g. anthropic/claude-sonnet-4-6), logs to spend_logs and renders in the UI normally — response is natively anthropic-shape, no Responses API translation, AnthropicResponse.model_validate(...) passes. So the bug surface is specifically:

call_type=anthropic_messages + non-Anthropic backend (Responses API bridge) + streaming response.

Expected behavior

Either:

  • _handle_anthropic_messages_response_logging recognizes that result is a streaming Responses API event and translates it (using the same translation path that already exists for the user-facing wrapper) before validating, or
  • it serializes the result to its anthropic equivalent for spend_logs in a degraded form (model + token counts + final text) when full validation fails, or
  • at minimum the row should still land in spend_logs with whatever metadata is available, rather than being dropped entirely.

Relevant Issues

Adjacent but distinct: #23841 (multiple cross-route bugs in the same /v1/messages → OpenAI path) does not appear to cover this specific logging failure.

Are you a ML Ops Team?

No

What LiteLLM version are you on ?

v1.85.0

Twitter / LinkedIn details

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Either:

  • _handle_anthropic_messages_response_logging recognizes that result is a streaming Responses API event and translates it (using the same translation path that already exists for the user-facing wrapper) before validating, or
  • it serializes the result to its anthropic equivalent for spend_logs in a degraded form (model + token counts + final text) when full validation fails, or
  • at minimum the row should still land in spend_logs with whatever metadata is available, rather than being dropped entirely.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

litellm - 💡(How to fix) Fix [Bug]: anthropic_messages logging silently drops spend_logs rows for cross-route to OpenAI Responses backend