run-llama/llama_index · warning · ValueError

Got empty streaming response

Error message

Got empty streaming response

What it means

MutableMappingKVStore.from_persist_path always raises NotImplementedError; the signature exists purely to satisfy type checkers (note it is even missing a @classmethod decorator). Only concrete stores such as SimpleKVStore implement real from_persist_path construction; calling it on the base class means you attempted to load persisted state into a store type that cannot load it.

Source

Thrown at llama-index-core/llama_index/core/agent/workflow/base_agent.py:342

                raw = (
                    last_response.raw.model_dump()
                    if isinstance(last_response.raw, BaseModel)
                    else last_response.raw
                )
                if ctx.is_running:
                    ctx.write_event_to_stream(
                        AgentStream(
                            delta=last_response.delta or "",
                            response=last_response.message.content or "",
                            raw=raw,
                            current_agent_name=self.name,
                            thinking_delta=last_response.additional_kwargs.get(
                                "thinking_delta", None
                            ),
                        )
                    )
            if last_response is None:
                raise ValueError("Got empty streaming response")
            return last_response
        else:
            return await target_llm.achat(llm_input)

    async def _call_tool(
        self,
        ctx: Context,
        tool: AsyncBaseTool,
        tool_input: dict,
    ) -> ToolOutput:
        """Call the given tool with the given input."""
        try:
            if (
                isinstance(tool, FunctionTool)
                and tool.requires_context
                and tool.ctx_param_name is not None
            ):
                new_tool_input = {**tool_input}

View on GitHub (pinned to afd0fef371)

Solutions

  1. Construct the concrete class: SimpleKVStore.from_persist_path('store.json').
  2. Add a real from_persist_path (with @classmethod) to your custom MutableMappingKVStore subclass that reads the JSON and populates the mapping.
  3. Dispatch on concrete type in factory code instead of the base class.

Example fix

# before
store = MutableMappingKVStore.from_persist_path("store.json")  # NotImplementedError

# after
from llama_index.core.storage.kvstore.simple_kvstore import SimpleKVStore
store = SimpleKVStore.from_persist_path("store.json")
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.storage.kvstore.types import MutableMappingKVStore
if type(store).from_persist_path is MutableMappingKVStore.from_persist_path:
    raise TypeError('construct SimpleKVStore explicitly')
store = StoreCls.from_persist_path(path)

Type guard

def can_load_from_path(store_cls) -> bool:
    return store_cls.from_persist_path is not MutableMappingKVStore.from_persist_path

Try / catch

try:
    store = Store.from_persist_path(p)
except NotImplementedError:
    store = SimpleKVStore.from_persist_path(p)

Prevention

When it happens

Trigger: Invoking MutableMappingKVStore.from_persist_path('store.json') directly; generic factory code annotated with the base type dispatching to from_persist_path; a custom subclass that inherits the raising implementation.

Common situations: Refactors that changed a variable's static type from SimpleKVStore to MutableMappingKVStore; IDE autocompletion offering from_persist_path on the base class; DI containers constructing stores from base-type references.

Related errors


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