{"record":{"id":"0f576fb49f521cf2","repo":"run-llama/llama_index","slug":"num-nodes-must-be-1","errorCode":null,"errorMessage":"num_nodes must be >= 1","messagePattern":"num_nodes must be >= 1","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/extractors/metadata_extractors.py","lineNumber":98,"sourceCode":"    combine_template: str = Field(\n        default=DEFAULT_TITLE_COMBINE_TEMPLATE,\n        description=\"The prompt template to merge titles with.\",\n    )\n\n    def __init__(\n        self,\n        llm: Optional[LLM] = None,\n        # TODO: llm_predictor arg is deprecated\n        llm_predictor: Optional[LLM] = None,\n        nodes: int = 5,\n        node_template: str = DEFAULT_TITLE_NODE_TEMPLATE,\n        combine_template: str = DEFAULT_TITLE_COMBINE_TEMPLATE,\n        num_workers: int = DEFAULT_NUM_WORKERS,\n        **kwargs: Any,\n    ) -> None:\n        \"\"\"Init params.\"\"\"\n        if nodes < 1:\n            raise ValueError(\"num_nodes must be >= 1\")\n\n        super().__init__(\n            llm=llm or llm_predictor or Settings.llm,\n            nodes=nodes,\n            node_template=node_template,\n            combine_template=combine_template,\n            num_workers=num_workers,\n            **kwargs,\n        )\n\n    @classmethod\n    def class_name(cls) -> str:\n        return \"TitleExtractor\"\n\n    async def aextract(self, nodes: Sequence[BaseNode]) -> List[Dict]:\n        nodes_by_doc_id = self.separate_nodes_by_ref_id(nodes)\n        titles_by_doc_id = await self.extract_titles(nodes_by_doc_id)\n        return [{\"document_title\": titles_by_doc_id[node.ref_doc_id]} for node in nodes]","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/extractors/metadata_extractors.py#L80-L116","documentation":"Raised by TitleExtractor.__init__ when the nodes parameter (the number of nodes/documents to combine into a generated title, default 5) is less than 1. A title is produced by feeding `nodes` chunks to the LLM with node_template/combine_template, so zero documents makes the prompt meaningless and is rejected at construction time.","triggerScenarios":"Constructing TitleExtractor(nodes=0) — often because a variable (e.g. len(some_list) computed before data loads, or a CLI arg parsed as 0) is passed straight into the constructor.","commonSituations":"Config files with nodes: 0 copied from a template; arithmetic like max(0, n - k) producing 0; argparse with a default of 0 for a --title-nodes flag.","solutions":["Pass nodes >= 1, e.g. the default TitleExtractor() or TitleExtractor(nodes=5).","Validate/ clamp the value at the config boundary: nodes = max(1, configured_nodes).","If the intent was 'no title extraction', remove TitleExtractor from the transformation pipeline rather than zeroing nodes."],"exampleFix":"# before\nextractor = TitleExtractor(nodes=max(0, num_docs - 10))\n\n# after\nextractor = TitleExtractor(nodes=max(1, num_docs - 10))\n# or omit TitleExtractor entirely when num_docs <= 10","handlingStrategy":"validation","validationCode":"num_nodes = int(config.get(\"title_nodes\", 5))\nif num_nodes < 1:\n    raise ValueError(f\"title_nodes must be >= 1, got {num_nodes}\")\nextractor = TitleExtractor(nodes=num_nodes)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp numeric config at the boundary: max(1, value).","Type and range-validate user inputs (CLI/argparse) before constructing extractors.","Default to omitting the parameter rather than passing 0."],"tags":["validation","configuration","constructor","off-by-one"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}