run-llama/llama_index · error · ValueError

chat_stream is None. Cannot write to history without chat_st

Error message

chat_stream is None. Cannot write to history without chat_stream.

What it means

StreamingAgentChatResponse.write_response_to_history() consumes the synchronous LLM stream (self.chat_stream) to persist the final message into memory. The object is created with chat_stream=None by default, so calling this method before the engine has attached a stream is a programming error — there is literally nothing to write to history.

Source

Thrown at llama-index-core/llama_index/core/chat_engine/types.py:179

    def put_in_queue(self, delta: Optional[str]) -> None:
        self.queue.put_nowait(delta)
        self.is_function_not_none_thread_event.set()

    def aput_in_queue(self, delta: Optional[str]) -> None:
        assert self.aqueue is not None
        assert self.new_item_event is not None

        self.aqueue.put_nowait(delta)
        self.new_item_event.set()

    @dispatcher.span
    def write_response_to_history(
        self,
        memory: BaseMemory,
        on_stream_end_fn: Optional[Callable] = None,
    ) -> None:
        if self.chat_stream is None:
            raise ValueError(
                "chat_stream is None. Cannot write to history without chat_stream."
            )

        # try/except to prevent hanging on error
        dispatcher.event(StreamChatStartEvent())
        try:
            final_text = ""
            for chat in self.chat_stream:
                self.is_function = is_function(chat.message)
                if chat.delta:
                    dispatcher.event(
                        StreamChatDeltaReceivedEvent(
                            delta=chat.delta,
                        )
                    )
                    self.put_in_queue(chat.delta)
                final_text += chat.delta or ""
            if self.is_function is not None:  # if loop has gone through iteration

View on GitHub (pinned to afd0fef371)

Solutions

  1. Use the matching method: astream_chat() responses need await response.awrite_response_to_history(memory), stream_chat() responses need response.write_response_to_history(memory)
  2. If you built the response yourself, pass the generator: StreamingAgentChatResponse(chat_stream=llm.stream_chat(...))
  3. In normal agent usage you rarely call this directly — let agent.stream_chat() handle history writing and just iterate response.response_gen

Example fix

// before
response = await agent.astream_chat("hi")
response.write_response_to_history(memory)  # ValueError: chat_stream is None

// after
response = await agent.astream_chat("hi")
await response.awrite_response_to_history(memory)
Defensive patterns

Strategy: validation

Validate before calling

if response.chat_stream is None:
    raise RuntimeError("response has no sync stream; use awrite_response_to_history")

Type guard

from llama_index.core.chat_engine.types import StreamingAgentChatResponse

def has_sync_stream(resp: StreamingAgentChatResponse) -> bool:
    return resp.chat_stream is not None

Try / catch

try:
    response.write_response_to_history(memory)
except ValueError as e:
    if "chat_stream is None" in str(e):
        await response.awrite_response_to_history(memory)  # async fallback
    else:
        raise

Prevention

When it happens

Trigger: Calling write_response_to_history(memory) on a StreamingAgentChatResponse obtained via agent.astream_chat() (which sets achat_stream, not chat_stream); calling it on a manually constructed StreamingAgentChatResponse(); calling it twice after the stream was already consumed elsewhere.

Common situations: Mixing sync and async code paths — obtaining the response from astream_chat() but using the sync write_response_to_history; building custom agents/workflows that construct StreamingAgentChatResponse() directly and forget to pass chat_stream; re-processing a response object after iteration completed.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/e31b98d76f1238c9. Report an issue: GitHub.