microsoft/semantic-kernel · error · ServiceInvalidResponseError

Invalid response type from Ollama streaming chat completion.

Error message

Invalid response type from Ollama streaming chat completion. Expected mapping or ChatResponse but got {type(part)}.

What it means

Raised as ServiceInvalidResponseError while iterating the streaming AsyncIterator, when an individual yielded `part` is neither a `ChatResponse` nor a `Mapping`. The outer iterator type was fine (passed the 1115 check), but one of its elements has an unrecognized shape, so the connector cannot build a StreamingChatMessageContent from it.

Source

Thrown at python/semantic_kernel/connectors/ai/ollama/services/ollama_chat_completion.py:211

            messages=prepared_chat_history,
            stream=True,
            **settings.prepare_settings_dict(),
        )

        if not isinstance(response_object, AsyncIterator):
            raise ServiceInvalidResponseError(
                "Invalid response type from Ollama streaming chat completion. "
                f"Expected AsyncIterator but got {type(response_object)}."
            )

        async for part in response_object:
            if isinstance(part, ChatResponse):
                yield [self._create_streaming_chat_message_content_from_chat_response(part, function_invoke_attempt)]
                continue
            if isinstance(part, Mapping):
                yield [self._create_streaming_chat_message_content(part, function_invoke_attempt)]
                continue
            raise ServiceInvalidResponseError(
                "Invalid response type from Ollama streaming chat completion. "
                f"Expected mapping or ChatResponse but got {type(part)}."
            )

    # endregion

    def _create_streaming_chat_message_content_from_chat_response(
        self,
        response: ChatResponse,
        function_invoke_attempt: int,
    ) -> StreamingChatMessageContent:
        """Create a chat message content from the response."""
        items: list[STREAMING_ITEM_TYPES] = []
        if response.message.content:
            items.append(
                StreamingTextContent(
                    choice_index=0,
                    text=response.message.content,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure every item your client's streaming generator yields is an ollama ChatResponse or a dict/Mapping.
  2. Pin/align the ollama python SDK version with the connector's expected chunk type.
  3. In tests, yield only dicts or ChatResponse instances from the fake async generator.

Example fix

# before
async def chat(self, **kw):
    yield 'partial text'   # not a ChatResponse or Mapping

# after
async def chat(self, **kw):
    yield {'message': {'role':'assistant','content':'partial text'}}
Defensive patterns

Strategy: type-guard

Validate before calling

# Verify each streamed part type in a smoke test
from ollama import ChatResponse
from collections.abc import Mapping, AsyncIterator
async for part in await svc.client.chat(model=svc.ai_model_id, messages=[...], stream=True):
    assert isinstance(part, (ChatResponse, Mapping)), f'bad part type {type(part)}'

Type guard

from ollama import ChatResponse
from collections.abc import Mapping

def is_valid_ollama_stream_part(part) -> bool:
    return isinstance(part, (ChatResponse, Mapping))

Try / catch

from semantic_kernel.exceptions import ServiceInvalidResponseError
try:
    async for chunk in svc._inner_get_streaming_chat_message_contents(chat_history, settings):
        ...
except ServiceInvalidResponseError as e:
    if 'Expected mapping or ChatResponse' in str(e):
        raise RuntimeError('streaming chunk type unsupported by this ollama version') from e
    raise

Prevention

When it happens

Trigger: A streaming response from the ollama client that mixes in an unexpected object type among the chunks - e.g. a SDK version that yields a different chunk class, a custom async generator yielding heterogeneous items, or a server that emits an error/control object mid-stream.

Common situations: Upgrading the ollama SDK so its stream yields new chunk types; a custom proxy injecting metadata objects into the stream; a test fake generator yielding strings instead of ChatResponse/dict.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/a8811a0985b08f6c. Report an issue: GitHub.