run-llama/llama_index · error · NotImplementedError

This query engine does not support _aquery.

Error message

This query engine does not support _aquery.

What it means

The async twin of the previous stub: CustomQueryEngine._aquery(query_bundle) raises NotImplementedError because the class supports only the string-based async surface, acustom_query() (defaulted to run the sync custom_query). Hitting it means something drove the engine through the QueryBundle-based async path that CustomQueryEngine intentionally does not implement.

Source

Thrown at llama-index-core/llama_index/core/query_engine/custom.py:77

                Response(raw_response)
                if isinstance(raw_response, str)
                else raw_response
            )

    @abstractmethod
    def custom_query(self, query_str: str) -> STR_OR_RESPONSE_TYPE:
        """Run a custom query."""

    async def acustom_query(self, query_str: str) -> STR_OR_RESPONSE_TYPE:
        """Run a custom query asynchronously."""
        # by default, just run the synchronous version
        return self.custom_query(query_str)

    def _query(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
        raise NotImplementedError("This query engine does not support _query.")

    async def _aquery(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
        raise NotImplementedError("This query engine does not support _aquery.")

View on GitHub (pinned to afd0fef371)

Solutions

  1. Use the public async API: await engine.aquery('your question') — it calls custom_query under the hood.
  2. If the _aquery contract is required, base your class on BaseQueryEngine/RetrieverQueryEngine and implement _aquery yourself.
  3. Override acustom_query() if your custom logic is genuinely async, instead of trying to make _aquery work.
  4. Search the codebase for `_aquery(` and route those call sites through aquery().

Example fix

# before
resp = await engine._aquery(QueryBundle(query_str="summary?"))  # NotImplementedError

# after
resp = await engine.aquery("summary?")  # -> acustom_query -> custom_query
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.query_engine.custom import CustomQueryEngine

def assert_aqueryable(engine) -> None:
    if isinstance(engine, CustomQueryEngine) and not hasattr(engine, "_aquery_impl"):
        # fine: aquery(str) routes to acustom_query; just never call _aquery directly
        pass

def run_query(engine, q: str):
    return engine.aquery(q) if hasattr(engine, "aquery") else engine.query(q)

Type guard

from llama_index.core.query_engine.custom import CustomQueryEngine

def supports_string_aquery(engine) -> bool:
    return isinstance(engine, CustomQueryEngine) and callable(getattr(engine, "acustom_query", None))

Prevention

When it happens

Trigger: Awaiting engine._aquery(query_bundle) directly, or plugging a CustomQueryEngine into async orchestration (agents, pipelines, routers) that awaits the protected _aquery API rather than calling the overridden aquery(str). engine.aquery('question') is fine — it dispatches to custom_query.

Common situations: Async agent frameworks or benchmark harnesses that standardize on BaseQueryEngine internals; refactors that swapped a RetrieverQueryEngine for a CustomQueryEngine without changing call sites; tests calling protected methods to 'skip boilerplate'.

Related errors


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