{"record":{"id":"ec5ef9defe7d55a0","repo":"run-llama/llama_index","slug":"node-id-node-id-str-not-found-in-fetched-nodes","errorCode":null,"errorMessage":"Node ID {node_id_str} not found in fetched nodes. ","messagePattern":"Node ID (.+?) not found in fetched nodes\\. ","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/indices/vector_store/retrievers/retriever.py","lineNumber":203,"sourceCode":"        new_nodes: List[BaseNode] = []\n\n        if query_result.nodes:\n            for node in list(query_result.nodes):\n                node_id_str = str(node.node_id)\n                if node_id_str in fetched_nodes_by_id:\n                    new_nodes.append(fetched_nodes_by_id[node_id_str])\n                else:\n                    # We did not fetch a replacement node, so we keep the original node\n                    new_nodes.append(node)\n        elif query_result.ids:\n            for node_id in query_result.ids:\n                if node_id not in self._index.index_struct.nodes_dict:\n                    raise KeyError(f\"Node ID {node_id} not found in index. \")\n                node_id_str = str(self._index.index_struct.nodes_dict[node_id])\n                if node_id_str in fetched_nodes_by_id:\n                    new_nodes.append(fetched_nodes_by_id[node_id_str])\n                else:\n                    raise KeyError(\n                        f\"Node ID {node_id_str} not found in fetched nodes. \"\n                    )\n        elif query_result.ids is None and query_result.nodes is None:\n            raise ValueError(\n                \"Vector store query result should return at least one of nodes or ids.\"\n            )\n        return new_nodes\n\n    def _convert_nodes_to_scored_nodes(\n        self, query_result: VectorStoreQueryResult\n    ) -> List[NodeWithScore]:\n        \"\"\"Create scored nodes from the vector store query result.\"\"\"\n        node_with_scores: List[NodeWithScore] = []\n\n        for ind, node in enumerate(list(query_result.nodes or [])):\n            score: Optional[float] = None\n            if query_result.similarities is not None:\n                score = query_result.similarities[ind]","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/indices/vector_store/retrievers/retriever.py#L185-L221","documentation":"VectorIndexRetriever._build_nodes raises KeyError(f'Node ID {node_id_str} not found in fetched nodes.') when a query-result id maps via index_struct.nodes_dict to a node id that is absent from fetched_nodes_by_id (the nodes just fetched from the docstore). The mapping exists but the docstore no longer holds that node — the index struct and the docstore are out of sync, typically after the docstore was swapped, partially persisted, or cleaned while the index struct still references the nodes.","triggerScenarios":"Loading storage where index_struct.json was persisted but docstore.json is stale/missing nodes; deleting nodes from the docstore directly without updating the index; mixing StorageContexts from different runs (vector store + index struct from run A, docstore from run B).","commonSituations":"Persisting only part of the storage context; manual docstore edits; version-migration scripts that rebuilt one artifact but not the others.","solutions":["Re-ingest into a clean storage context so vector store, index_struct, and docstore are written together.","When reloading, load StorageContext.from_defaults(persist_dir=...) from one directory containing all artifacts from the same write.","If the docstore is authoritative, rebuild the index struct from the docstore's nodes."],"exampleFix":"# before\nstorage = StorageContext.from_defaults(vector_store=store)  # docstore from elsewhere\nindex = load_index_from_storage(storage)\nnodes = index.as_retriever().retrieve(\"q\")  # KeyError: ... not found in fetched nodes\n\n# after\n# re-ingest once, persist everything together\nstorage = StorageContext.from_defaults(vector_store=store)\nindex = VectorStoreIndex.from_documents(docs, storage_context=storage)\nstorage.persist(persist_dir=\"./storage\")\n# later: storage = StorageContext.from_defaults(persist_dir=\"./storage\")","handlingStrategy":"try-catch","validationCode":"def docstore_covers_index_nodes(index) -> bool:\n    node_ids = set(index.index_struct.nodes_dict.values())\n    have = set(index.docstore.get_all_document_holder().keys()) if hasattr(index.docstore, \"get_all_document_holder\") else set()\n    return node_ids <= have or index.docstore.get_nodes(list(node_ids)[:5]) is not None","typeGuard":null,"tryCatchPattern":"try:\n    nodes = retriever.retrieve(query_str)\nexcept KeyError as e:\n    if \"not found in fetched nodes\" in str(e):\n        raise RuntimeError(\n            \"docstore/index_struct mismatch: rebuild the index with a single consistent StorageContext\"\n        ) from e\n    raise","preventionTips":["Persist all storage artifacts (index_struct, docstore, vector store) atomically from one StorageContext.persist().","Never mix artifacts from different runs or persist_dirs.","After partial deletes or migrations, rebuild the index rather than patching one artifact."],"tags":["vector-store","storage-consistency","docstore","llama-index"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}