{"record":{"id":"65ff6db49ccc10e4","repo":"run-llama/llama_index","slug":"index-was-constructed-without-building-trees-but","errorCode":null,"errorMessage":"Index was constructed without building trees, but retriever mode {retriever_mode} requires trees.","messagePattern":"Index was constructed without building trees, but retriever mode (.+?) requires trees\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/indices/tree/base.py","lineNumber":133,"sourceCode":"\n        if retriever_mode == TreeRetrieverMode.SELECT_LEAF:\n            return TreeSelectLeafRetriever(self, object_map=self._object_map, **kwargs)\n        elif retriever_mode == TreeRetrieverMode.SELECT_LEAF_EMBEDDING:\n            embed_model = embed_model or Settings.embed_model\n            return TreeSelectLeafEmbeddingRetriever(\n                self, embed_model=embed_model, object_map=self._object_map, **kwargs\n            )\n        elif retriever_mode == TreeRetrieverMode.ROOT:\n            return TreeRootRetriever(self, object_map=self._object_map, **kwargs)\n        elif retriever_mode == TreeRetrieverMode.ALL_LEAF:\n            return TreeAllLeafRetriever(self, object_map=self._object_map, **kwargs)\n        else:\n            raise ValueError(f\"Unknown retriever mode: {retriever_mode}\")\n\n    def _validate_build_tree_required(self, retriever_mode: TreeRetrieverMode) -> None:\n        \"\"\"Check if index supports modes that require trees.\"\"\"\n        if retriever_mode in REQUIRE_TREE_MODES and not self.build_tree:\n            raise ValueError(\n                \"Index was constructed without building trees, \"\n                f\"but retriever mode {retriever_mode} requires trees.\"\n            )\n\n    def _build_index_from_nodes(\n        self, nodes: Sequence[BaseNode], **build_kwargs: Any\n    ) -> IndexGraph:\n        \"\"\"Build the index from nodes.\"\"\"\n        index_builder = GPTTreeIndexBuilder(\n            self.num_children,\n            self.summary_template,\n            llm=self._llm,\n            use_async=self._use_async,\n            show_progress=self._show_progress,\n            docstore=self._docstore,\n        )\n        return index_builder.build_from_nodes(nodes, build_tree=self.build_tree)\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/indices/tree/base.py#L115-L151","documentation":"TreeIndex._validate_build_tree_required raises ValueError when the requested retriever mode is in REQUIRE_TREE_MODES ({SELECT_LEAF, SELECT_LEAF_EMBEDDING, ROOT}) but the index was constructed with build_tree=False. build_tree=False stores only leaf nodes with no LLM-generated summary hierarchy, so any mode that must traverse or select among internal tree summaries cannot work. Only ALL_LEAF mode (brute-force embedding search over leaves) is valid on a treeless index.","triggerScenarios":"TreeIndex(nodes, build_tree=True, use_async=True) omitted / set False (e.g. building from existing Documents with build_tree=False for cheap ingestion), then calling as_retriever(retriever_mode=TreeRetrieverMode.SELECT_LEAF).","commonSituations":"Choosing build_tree=False to skip LLM summarization cost at ingest, then expecting default select_leaf retrieval to still work; loading an index persisted by a pipeline that built it treeless; parameter renamed/added across versions so old scripts silently default to False.","solutions":["If you need leaf-selection retrieval, rebuild the index with build_tree=True: TreeIndex(nodes, build_tree=True).","If you want to keep the cheap treeless index, retrieve with retriever_mode=TreeRetrieverMode.ALL_LEAF (embedding search over leaves).","Decide the retrieval strategy before ingestion — the trade-off (LLM cost now vs. traversal later) is fixed at build time."],"exampleFix":"# before\nindex = TreeIndex(nodes, build_tree=False)\nretriever = index.as_retriever()  # default SELECT_LEAF -> ValueError\n\n# after (option A: build the tree)\nindex = TreeIndex(nodes, build_tree=True)\nretriever = index.as_retriever()\n# after (option B: stay treeless)\nretriever = index.as_retriever(retriever_mode=TreeRetrieverMode.ALL_LEAF)","handlingStrategy":"validation","validationCode":"from llama_index.core.indices.tree.base import REQUIRE_TREE_MODES, TreeRetrieverMode\n\ndef can_use_mode(index, mode: TreeRetrieverMode) -> bool:\n    return index.build_tree or mode not in REQUIRE_TREE_MODES\n\n# usage: assert can_use_mode(index, TreeRetrieverMode.SELECT_LEAF)","typeGuard":"from llama_index.core.indices.tree.base import REQUIRE_TREE_MODES\n\ndef mode_requires_tree(mode) -> bool:\n    return mode in REQUIRE_TREE_MODES","tryCatchPattern":"try:\n    retriever = index.as_retriever(retriever_mode=mode)\nexcept ValueError:\n    retriever = index.as_retriever(retriever_mode=TreeRetrieverMode.ALL_LEAF)  # treeless fallback","preventionTips":["Decide retrieval strategy before ingestion: SELECT_LEAF*/ROOT require build_tree=True.","For treeless (cheap) ingestion, plan on ALL_LEAF embedding retrieval.","Check index.build_tree in your own code before offering tree-traversal modes."],"tags":["tree-index","config","retriever","llama-index"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}