run-llama/llama_index · error · ValueError

Failed to select query engine

Error message

Failed to select query engine

What it means

In RouterQueryEngine._query (sync), after the selector picks a query engine it indexes self._query_engines[result.ind]. If that lookup raises ValueError (index out of range because the LLM selector returned an invalid index), it is re-raised as 'Failed to select query engine' with the original as cause.

Source

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

                    selected_query_engine = self._query_engines[engine_ind]
                    responses.append(selected_query_engine.query(query_bundle))

                if len(responses) > 1:
                    final_response = combine_responses(
                        self._summarizer, responses, query_bundle
                    )
                else:
                    final_response = responses[0]
            else:
                try:
                    selected_query_engine = self._query_engines[result.ind]
                    log_str = f"Selecting query engine {result.ind}: {result.reason}."
                    logger.info(log_str)
                    if self._verbose:
                        print_text(log_str + "\n", color="pink")
                except ValueError as e:
                    raise ValueError("Failed to select query engine") from e

                final_response = selected_query_engine.query(query_bundle)

            # add selected result
            final_response.metadata = final_response.metadata or {}
            final_response.metadata["selector_result"] = result

            query_event.on_end(payload={EventPayload.RESPONSE: final_response})

        return final_response

    async def _aquery(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
        with self.callback_manager.event(
            CBEventType.QUERY, payload={EventPayload.QUERY_STR: query_bundle.query_str}
        ) as query_event:
            result = await self._selector.aselect(self._metadatas, query_bundle)

            if len(result.inds) > 1:

View on GitHub (pinned to afd0fef371)

Solutions

  1. Use a stronger instruction-following LLM for routing (e.g. an OpenAI function-calling model with PydanticSingleSelector)
  2. Pass an explicit selector: RouterQueryEngine(..., selector=get_selector_from_llm(llm)) with a reliable LLM, rather than relying on the default
  3. Verify the QueryEngineTool list is small and well-differentiated so the selector's numbered choice is unambiguous
  4. Catch ValueError and retry the query or fall back to a default engine

Example fix

// before
router = RouterQueryEngine(selector=LLMSingleSelector.from_defaults(llm=weak_llm), query_engine_tools=tools)
resp = router.query(q)

// after
from llama_index.core.selectors import PydanticSingleSelector
router = RouterQueryEngine(
    selector=PydanticSingleSelector.from_defaults(llm=strong_llm),
    query_engine_tools=tools,
)
resp = router.query(q)
Defensive patterns

Strategy: retry

Validate before calling

# Validate selector sanity before querying: choices must match engines
assert router_engine._selector is not None
# keep engine/tool counts aligned at construction time:
# RouterQueryEngine(query_engine_tools=tools) builds both from the same list, prefer that API

Try / catch

try:
    resp = router_engine.query(q)
except ValueError as e:
    if "Failed to select query engine" in str(e) and e.__cause__ is not None:
        resp = router_engine.query(q)  # one retry; selector output is nondeterministic
    else:
        raise

Prevention

When it happens

Trigger: Single-selection routing where the selector LLM returns result.ind outside 0..len(query_engines)-1 (e.g. returns 2 when only 2 engines exist, or a tool index misaligned with the choices list).

Common situations: Weak or non-instruct LLM that fails to follow the selector output format; a custom selector whose choices list order does not match the query_engines list; flaky structured-output parsing in the Pydantic/LLM selector.

Related errors


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