{"record":{"id":"7f15064158243639","repo":"zylon-ai/private-gpt","slug":"must-provide-either-text-or-context-filter","errorCode":null,"errorMessage":"Must provide either text or context_filter","messagePattern":"Must provide either text or context_filter","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/tools/builders/summary_builder.py","lineNumber":130,"sourceCode":"        self._validate_context(context_filter)\n        return ContextRetriever(self.content_service, context_filter)  # type: ignore\n\n    def _create_composite_retriever(\n        self,\n        texts: list[str] | None = None,\n        context_filter: ContextFilter | None = None,\n    ) -> \"Retriever\":\n        \"\"\"Create appropriate retriever(s) based on input parameters.\"\"\"\n        retrievers: list[Retriever] = []\n\n        if texts:\n            retrievers.append(self._create_text_retriever(texts))\n\n        if context_filter:\n            retrievers.append(self._create_context_retriever(context_filter))\n\n        if not retrievers:\n            raise ValueError(\"Must provide either text or context_filter\")\n\n        return CompositeRetriever(retrievers) if len(retrievers) > 1 else retrievers[0]\n\n    def build(\n        self,\n        texts: list[str] | None = None,\n        context_filter: ContextFilter | None = None,\n        stop_condition_fn: Callable[[str], Awaitable[bool]] | None = None,\n        llm: LLM | None = None,\n        timeout: float | None = None,\n    ) -> SummarizeWorkflow:\n        \"\"\"Build a summarize workflow.\"\"\"\n        retriever = self._create_composite_retriever(\n            texts=texts if texts else None,\n            context_filter=context_filter if context_filter else None,\n        )\n\n        return SummarizeWorkflow(","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/tools/builders/summary_builder.py#L112-L148","documentation":"ValueError from SummaryToolBuilder._create_retriever: retrievers are appended only for non-empty texts (InMemoryRetriever) and for a truthy context_filter (context retriever); if both are absent the list stays empty and the builder refuses to return a retriever that could never fetch content.","triggerScenarios":"Calling build()/the summary tool with texts=None (or empty list) AND context_filter=None at the same time; also an empty texts list [] is falsy, so texts=[] alone triggers it.","commonSituations":"Agent workflow forwards user input where the user supplied neither documents nor text; upstream code splits input into texts/context and both branches drop the value; caller passes texts=[] expecting it to mean 'use everything'.","solutions":["Pass at least one non-empty string in texts, or a valid context_filter with a collection.","Fix upstream input routing so exactly one of the two inputs is always populated when the summary tool is invoked.","If no content is available, skip calling the summary tool rather than invoking it with empty inputs."],"exampleFix":"# before\nworkflow = builder.build(texts=[], context_filter=None)\n\n# after\nworkflow = builder.build(texts=[long_document_text], context_filter=None)","handlingStrategy":"validation","validationCode":"if not texts and not context_filter:\n    raise ValueError(\"summary tool needs texts or context_filter\")\nworkflow = builder.build(texts=texts or None, context_filter=context_filter)","typeGuard":"def has_summary_input(texts, context_filter) -> bool:\n    return bool(texts) or context_filter is not None","tryCatchPattern":null,"preventionTips":["Remember texts=[] is falsy — an empty list counts as 'no texts' and will trigger the error.","Skip the summary tool entirely when the user provided no content to summarize."],"tags":["validation","summary","retriever"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}