run-llama/llama_index · error · ValueError

AsyncStreamingResponse not supported in sync code.

Error message

AsyncStreamingResponse not supported in sync code.

What it means

combine_responses() in RouterQueryEngine merges sub-engine responses synchronously. It accepts Response, StreamingResponse, and PydanticResponse, but if a sub-engine returned an AsyncStreamingResponse there is no sync way to consume it, so it raises ValueError immediately.

Source

Thrown at llama-index-core/llama_index/core/query_engine/router_query_engine.py:47

from llama_index.core.tools.types import ToolMetadata
from llama_index.core.utils import print_text

logger = logging.getLogger(__name__)


def combine_responses(
    summarizer: TreeSummarize, responses: List[RESPONSE_TYPE], query_bundle: QueryBundle
) -> RESPONSE_TYPE:
    """Combine multiple response from sub-engines."""
    logger.info("Combining responses from multiple query engines.")

    response_strs = []
    source_nodes = []
    for response in responses:
        if isinstance(response, (StreamingResponse, PydanticResponse)):
            response_obj = response.get_response()
        elif isinstance(response, AsyncStreamingResponse):
            raise ValueError("AsyncStreamingResponse not supported in sync code.")
        else:
            response_obj = response
        source_nodes.extend(response_obj.source_nodes)
        response_strs.append(str(response))

    summary = summarizer.get_response(query_bundle.query_str, response_strs)

    if isinstance(summary, str):
        return Response(response=summary, source_nodes=source_nodes)
    elif isinstance(summary, BaseModel):
        return PydanticResponse(response=summary, source_nodes=source_nodes)
    elif isinstance(summary, Generator):
        return StreamingResponse(response_gen=summary, source_nodes=source_nodes)
    else:
        return AsyncStreamingResponse(response_gen=summary, source_nodes=source_nodes)


async def acombine_responses(

View on GitHub (pinned to afd0fef371)

Solutions

  1. Call `await router_engine.aquery(...)` instead of the sync `query(...)` when sub-engines are streaming/async
  2. Disable streaming on the sub-query engines (streaming=False) if you must use the sync API
  3. In a custom query engine, ensure _query() returns sync RESPONSE_TYPE objects (Response/StreamingResponse), never AsyncStreamingResponse

Example fix

// before
response = router_engine.query("compare sales and support docs")

// after
response = await router_engine.aquery("compare sales and support docs")
# or set streaming=False on sub-engines to keep sync query()
Defensive patterns

Strategy: validation

Validate before calling

from llama_index.core.response.schema import AsyncStreamingResponse

def responses_are_sync_safe(responses) -> bool:
    return not any(isinstance(r, AsyncStreamingResponse) for r in responses)

# or simply: choose the API up front
async def run(router, q):
    return await router.aquery(q)  # async path supports all response types

Type guard

from llama_index.core.response.schema import AsyncStreamingResponse

def is_async_streaming(r) -> bool:
    """True when the response cannot be consumed by sync code."""
    return isinstance(r, AsyncStreamingResponse)

Try / catch

try:
    resp = router.query(q)
except ValueError as e:
    if "AsyncStreamingResponse not supported in sync code" in str(e):
        resp = asyncio.run(router.aquery(q))
    else:
        raise

Prevention

When it happens

Trigger: Calling the sync path of RouterQueryEngine.query() where a multi-selection routes to sub-query engines that return async streaming responses (e.g. streaming sub-engines queried through a sync combine), hitting the isinstance(response, AsyncStreamingResponse) branch in combine_responses.

Common situations: Mixing streaming-enabled sub-query engines with the sync RouterQueryEngine.query() API instead of await aquery(), or a custom query engine whose sync query() accidentally returns an async generator-backed streaming response.

Related errors


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