run-llama/llama_index · error · ValueError

Vector store query result should return at least one of…

Error message

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

What it means

VectorIndexRetriever._build_nodes raises ValueError('Vector store query result should return at least one of nodes or ids.') when the VectorStoreQueryResult returned by the vector store has both nodes=None and ids=None (empty query results are fine — they are lists — but a result carrying neither field at all is not). This indicates a custom or buggy vector store integration whose query() builds VectorStoreQueryResult() without populating nodes/ids, since the built-in stores always set at least ids.

Solutions

  1. In the custom store's query(), always populate ids (and nodes when available): VectorStoreQueryResult(nodes=nodes or [], ids=[n.node_id for n in nodes], similarities=similarities).
  2. Upgrade the integration package if this comes from a third-party store — check its query implementation.
  3. Return empty lists rather than None for zero matches.

Example fix

# before (custom store)
def query(self, query, **kwargs):
    sims = self._search(query.query_embedding)
    return VectorStoreQueryResult(similarities=sims)  # ValueError upstream

# after
def query(self, query, **kwargs):
    nodes, sims = self._search(query.query_embedding)
    return VectorStoreQueryResult(
        nodes=nodes,
        ids=[n.node_id for n in nodes],
        similarities=sims,
    )
Defensive patterns

Strategy: validation

Validate before calling

from llama_index.core.vector_stores.types import VectorStoreQueryResult

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

Type guard

def has_nodes_or_ids(result) -> bool:
    return result is not None and (result.nodes is not None or result.ids is not None)

Try / catch

try:
    nodes = retriever.retrieve(query_str)
except ValueError as e:
    if "at least one of nodes or ids" in str(e):
        raise TypeError("custom vector store query() must populate nodes or ids") from e
    raise

Prevention

When it happens

Trigger: Implementing a custom BasePydanticVectorStore whose query() returns VectorStoreQueryResult() or only similarities; an integration version whose query path returns a bare result object on error/empty; monkeypatched stores in tests returning incomplete results.

Common situations: Writing a new vector store integration and forgetting to attach ids; test doubles that construct VectorStoreQueryResult() with only similarities; early-access integration releases with unpopulated fields on edge cases.

Related errors


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

Appendix: source

Thrown at llama-index-core/llama_index/core/indices/vector_store/retrievers/retriever.py:207

                node_id_str = str(node.node_id)
                if node_id_str in fetched_nodes_by_id:
                    new_nodes.append(fetched_nodes_by_id[node_id_str])
                else:
                    # We did not fetch a replacement node, so we keep the original node
                    new_nodes.append(node)
        elif query_result.ids:
            for node_id in query_result.ids:
                if node_id not in self._index.index_struct.nodes_dict:
                    raise KeyError(f"Node ID {node_id} not found in index. ")
                node_id_str = str(self._index.index_struct.nodes_dict[node_id])
                if node_id_str in fetched_nodes_by_id:
                    new_nodes.append(fetched_nodes_by_id[node_id_str])
                else:
                    raise KeyError(
                        f"Node ID {node_id_str} not found in fetched nodes. "
                    )
        elif query_result.ids is None and query_result.nodes is None:
            raise ValueError(
                "Vector store query result should return at least one of nodes or ids."
            )
        return new_nodes

    def _convert_nodes_to_scored_nodes(
        self, query_result: VectorStoreQueryResult
    ) -> List[NodeWithScore]:
        """Create scored nodes from the vector store query result."""
        node_with_scores: List[NodeWithScore] = []

        for ind, node in enumerate(list(query_result.nodes or [])):
            score: Optional[float] = None
            if query_result.similarities is not None:
                score = query_result.similarities[ind]

            node_with_scores.append(NodeWithScore(node=node, score=score))

        return node_with_scores

View on GitHub (pinned to afd0fef371)