run-llama/llama_index · error · ValueError

Vector store query result should return at least one of node

Error message

Vector store query result should return at least one of nodes or ids.

What it means

When a vector store query result comes back without nodes, the multimodal retriever tries to recover nodes from the docstore by id — and if ids are also None there is nothing to resolve, so it raises ValueError. Custom or partial vector store implementations that populate neither query_result.nodes nor query_result.ids hit this; well-behaved stores must return at least one of the two.

Source

Thrown at llama-index-core/llama_index/core/indices/multi_modal/retriever.py:236

        self,
        query_bundle_with_embeddings: QueryBundle,
        similarity_top_k: int,
        vector_store: BasePydanticVectorStore,
    ) -> List[NodeWithScore]:
        query = self._build_vector_store_query(
            query_bundle_with_embeddings, similarity_top_k
        )
        query_result = vector_store.query(query, **self._kwargs)
        return self._build_node_list_from_query_result(query_result)

    def _build_node_list_from_query_result(
        self, query_result: VectorStoreQueryResult
    ) -> List[NodeWithScore]:
        if query_result.nodes is None:
            # NOTE: vector store does not keep text and returns node indices.
            # Need to recover all nodes from docstore
            if query_result.ids is None:
                raise ValueError(
                    "Vector store query result should return at "
                    "least one of nodes or ids."
                )
            assert isinstance(self._index.index_struct, IndexDict)
            node_ids = [
                self._index.index_struct.nodes_dict[idx] for idx in query_result.ids
            ]
            nodes = self._docstore.get_nodes(node_ids)
            query_result.nodes = nodes
        else:
            # NOTE: vector store keeps text, returns nodes.
            # Only need to recover image or index nodes from docstore
            for i in range(len(query_result.nodes)):
                source_node = query_result.nodes[i].source_node
                if (not self._vector_store.stores_text) or (
                    source_node is not None and source_node.node_type != ObjectType.TEXT
                ):
                    node_id = query_result.nodes[i].node_id

View on GitHub (pinned to afd0fef371)

Solutions

  1. Fix the store's query() to populate at least ids (node ids matching what was stored) or full nodes in VectorStoreQueryResult.
  2. If using a third-party integration, upgrade it — and verify with a one-off query that the result carries nodes or ids.
  3. Pre-check the result contract in tests: run vector_store.query(...) once and assert result.nodes is not None or result.ids is not None.

Example fix

# before
def query(self, query, **kwargs):
    return VectorStoreQueryResult(similarities=sims)  # no nodes/ids -> ValueError

# after
def query(self, query, **kwargs):
    return VectorStoreQueryResult(nodes=retrieved_nodes, ids=retrieved_ids, similarities=sims)
Defensive patterns

Strategy: validation

Validate before calling

# smoke-test the store contract once at startup
q = vector_store.query(__import__('llama_index.core.vector_stores', fromlist=['VectorStoreQuery']).VectorStoreQuery(query_str="__probe__", similarity_top_k=1))
assert q.nodes is not None or q.ids is not None, "store must return nodes or ids"

Type guard

from llama_index.core.vector_stores.types import VectorStoreQueryResult

def result_resolvable(r: VectorStoreQueryResult) -> bool:
    return r.nodes is not None or r.ids is not None

Try / catch

try:
    nodes_with_scores = retriever.retrieve(q)
except ValueError as e:
    if "at least one of nodes or ids" in str(e):
        # custom store bug: fix query() to return ids/nodes; surface clearly
        raise RuntimeError("vector store query() must populate nodes or ids") from e
    raise

Prevention

When it happens

Trigger: Using a custom BasePydanticVectorStore subclass whose query() returns a VectorStoreQueryResult with nodes=None and ids=None; a store integration bug (e.g. returning only similarities/embeddings); querying a store whose results were built incompletely.

Common situations: Writing your own vector store adapter for a niche database and forgetting to map ids back; upgrading a store integration where the result-mapping code changed; multimodal retrieval against stores validated only on the single-modal path.

Related errors


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