{"record":{"id":"9307e5b2380ea6c6","repo":"BerriAI/litellm","slug":"stream-completed-response-is-invalid","errorCode":null,"errorMessage":"Stream completed response is invalid","messagePattern":"Stream completed response is invalid","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/completion_extras/litellm_responses_transformation/handler.py","lineNumber":84,"sourceCode":"                setattr(response, \"_hidden_params\", dict(hidden_params))\n            else:\n                for key, value in hidden_params.items():\n                    existing.setdefault(key, value)\n        return response\n\n    def _collect_response_from_stream(self, stream_iter: Any) -> \"ResponsesAPIResponse\":\n        for _ in stream_iter:\n            pass\n\n        completed: Final = getattr(stream_iter, \"completed_response\", None)\n        response_obj: Final = getattr(completed, \"response\", None) if completed else None\n        if response_obj is None:\n            raise ValueError(\"Stream ended without a completed response\")\n\n        hidden_params: Final = getattr(stream_iter, \"_hidden_params\", None)\n        response: Final = self._coerce_response_object(response_obj, hidden_params)\n        if not isinstance(response, ResponsesAPIResponse):\n            raise ValueError(\"Stream completed response is invalid\")\n        return response\n\n    async def _collect_response_from_stream_async(self, stream_iter: Any) -> \"ResponsesAPIResponse\":\n        async for _ in stream_iter:\n            pass\n\n        completed: Final = getattr(stream_iter, \"completed_response\", None)\n        response_obj: Final = getattr(completed, \"response\", None) if completed else None\n        if response_obj is None:\n            raise ValueError(\"Stream ended without a completed response\")\n\n        hidden_params: Final = getattr(stream_iter, \"_hidden_params\", None)\n        response: Final = self._coerce_response_object(response_obj, hidden_params)\n        if not isinstance(response, ResponsesAPIResponse):\n            raise ValueError(\"Stream completed response is invalid\")\n        return response\n\n    def validate_input_kwargs(self, kwargs: dict) -> ResponsesToCompletionBridgeHandlerInputKwargs:","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/completion_extras/litellm_responses_transformation/handler.py#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"Two litellm versions on sys.path (e.g. vendored copy + pip install) so isinstance checks compare different classes; heavily customized forks.","solutions":["Check for duplicate litellm installations: pip show litellm and python -c \"import litellm; print(litellm.__file__, litellm.__version__)\"","Update/reinstall litellm cleanly: pip install -U --force-reinstall litellm","Report with a repro if it persists on a clean latest install — it indicates an internal bug"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import litellm, litellm.types.utils\n\ndef single_litellm_install() -> bool:\n    import importlib.util\n    specs = [s for s in importlib.util.find_spec('litellm').submodule_search_locations or []]\n    return len({litellm.__file__}) == 1 and 'site-packages' in litellm.__file__","typeGuard":"from litellm.types.responses import ResponsesAPIResponse\n\ndef is_responses_api_response(obj: Any) -> TypeGuard[ResponsesAPIResponse]:\n    return isinstance(obj, ResponsesAPIResponse)","tryCatchPattern":"try:\n    response = handler._collect_response_from_stream(stream)\nexcept ValueError as e:\n    if 'Stream completed response is invalid' in str(e):\n        logger.exception('Internal bridge invariant failure — check for duplicate litellm installs')\n    raise","preventionTips":["Ensure exactly one litellm version is installed (no vendored duplicates)","Pin litellm in your lockfile and upgrade deliberately"],"tags":["responses-api","streaming","bridge","invariant","version"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}