BerriAI/litellm · error · ValueError

Stream completed response is invalid

Error message

Stream completed response is invalid

What it means

After collecting the stream, the bridge coerces the payload via _coerce_response_object and asserts the result isinstance of ResponsesAPIResponse. If coercion returned something else (possible only when the payload is a dict and model_construct returned an object that is not actually a ResponsesAPIResponse — e.g. severe version skew of the pydantic model, or the class identity differs between importer modules), it raises this invariant ValueError. It is an internal consistency check, not a user-configuration error.

Source

Thrown at litellm/completion_extras/litellm_responses_transformation/handler.py:84

                setattr(response, "_hidden_params", dict(hidden_params))
            else:
                for key, value in hidden_params.items():
                    existing.setdefault(key, value)
        return response

    def _collect_response_from_stream(self, stream_iter: Any) -> "ResponsesAPIResponse":
        for _ in stream_iter:
            pass

        completed: Final = getattr(stream_iter, "completed_response", None)
        response_obj: Final = getattr(completed, "response", None) if completed else None
        if response_obj is None:
            raise ValueError("Stream ended without a completed response")

        hidden_params: Final = getattr(stream_iter, "_hidden_params", None)
        response: Final = self._coerce_response_object(response_obj, hidden_params)
        if not isinstance(response, ResponsesAPIResponse):
            raise ValueError("Stream completed response is invalid")
        return response

    async def _collect_response_from_stream_async(self, stream_iter: Any) -> "ResponsesAPIResponse":
        async for _ in stream_iter:
            pass

        completed: Final = getattr(stream_iter, "completed_response", None)
        response_obj: Final = getattr(completed, "response", None) if completed else None
        if response_obj is None:
            raise ValueError("Stream ended without a completed response")

        hidden_params: Final = getattr(stream_iter, "_hidden_params", None)
        response: Final = self._coerce_response_object(response_obj, hidden_params)
        if not isinstance(response, ResponsesAPIResponse):
            raise ValueError("Stream completed response is invalid")
        return response

    def validate_input_kwargs(self, kwargs: dict) -> ResponsesToCompletionBridgeHandlerInputKwargs:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Check for duplicate litellm installations: pip show litellm and python -c "import litellm; print(litellm.__file__, litellm.__version__)"
  2. Update/reinstall litellm cleanly: pip install -U --force-reinstall litellm
  3. Report with a repro if it persists on a clean latest install — it indicates an internal bug
Defensive patterns

Strategy: try-catch

Validate before calling

import litellm, litellm.types.utils

def single_litellm_install() -> bool:
    import importlib.util
    specs = [s for s in importlib.util.find_spec('litellm').submodule_search_locations or []]
    return len({litellm.__file__}) == 1 and 'site-packages' in litellm.__file__

Type guard

from litellm.types.responses import ResponsesAPIResponse

def is_responses_api_response(obj: Any) -> TypeGuard[ResponsesAPIResponse]:
    return isinstance(obj, ResponsesAPIResponse)

Try / catch

try:
    response = handler._collect_response_from_stream(stream)
except ValueError as e:
    if 'Stream completed response is invalid' in str(e):
        logger.exception('Internal bridge invariant failure — check for duplicate litellm installs')
    raise

Prevention

When it happens

Trigger: Sync bridge usage where completed_response.response is a dict whose keys do not match the ResponsesAPIResponse schema, combined with a litellm version where model_construct still returns a mismatched instance; duplicate litellm installs importing different ResponsesAPIResponse classes.

Common situations: Two litellm versions on sys.path (e.g. vendored copy + pip install) so isinstance checks compare different classes; heavily customized forks.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/9307e5b2380ea6c6. Report an issue: GitHub.