run-llama/llama_index · error · ValueError

Retrieved more than one node.

Error message

Retrieved more than one node.

What it means

RetrieverRouterQueryEngine (deprecated) routes by retrieving exactly one node that maps to a query engine. Its _query currently supports only a single result: if the retriever returns more than one node, it raises ValueError('Retrieved more than one node.') instead of choosing among them.

Source

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

        self,
        retriever: BaseRetriever,
        node_to_query_engine_fn: Callable,
        callback_manager: Optional[CallbackManager] = None,
    ) -> None:
        self._retriever = retriever
        self._node_to_query_engine_fn = node_to_query_engine_fn
        super().__init__(callback_manager)

    def _get_prompt_modules(self) -> PromptMixinType:
        """Get prompt sub-modules."""
        # NOTE: don't include tools for now
        return {"retriever": self._retriever}

    def _query(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
        nodes_with_score = self._retriever.retrieve(query_bundle)
        # TODO: for now we only support retrieving one node
        if len(nodes_with_score) > 1:
            raise ValueError("Retrieved more than one node.")

        node = nodes_with_score[0].node
        query_engine = self._node_to_query_engine_fn(node)
        return query_engine.query(query_bundle)

    async def _aquery(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
        return self._query(query_bundle)


class ToolRetrieverRouterQueryEngine(BaseQueryEngine):
    """
    Tool Retriever router query engine.

    Selects a set of candidate query engines to execute a query.

    Args:
        retriever (ObjectRetriever): A retriever that retrieves a set of
            query engine tools.

View on GitHub (pinned to afd0fef371)

Solutions

  1. Construct the routing retriever with top_k=1: RetrieverRouterQueryEngine(index.as_retriever(similarity_top_k=1), ...)
  2. Keep exactly one node per query engine in the routing index
  3. Migrate to ToolRetrieverRouterQueryEngine, which handles multiple retrieved tools

Example fix

// before
router = RetrieverRouterQueryEngine(
    retriever=routing_index.as_retriever(),  # default top_k > 1
    node_to_query_engine_fn=fn,
)

// after
router = RetrieverRouterQueryEngine(
    retriever=routing_index.as_retriever(similarity_top_k=1),
    node_to_query_engine_fn=fn,
)
Defensive patterns

Strategy: validation

Validate before calling

retriever = routing_index.as_retriever(similarity_top_k=1)
router = RetrieverRouterQueryEngine(retriever=retriever, node_to_query_engine_fn=fn)

# belt and braces: dry-run retrieve to confirm single result
result = retriever.retrieve(QueryBundle(query_str="sample query"))
assert len(result) <= 1, f"router retriever returned {len(result)} nodes"

Prevention

When it happens

Trigger: Calling query()/aquery() on RetrieverRouterQueryEngine where the underlying retriever's top_k (default 2 or more, or similarity_top_k) yields multiple nodes above the threshold.

Common situations: Forgetting to set similarity_top_k=1 on the router's retriever; storing many tool-description nodes in the routing index so several match the query.

Related errors


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