zylon-ai/private-gpt · error · ValueError

Must provide either text or context_filter

Error message

Must provide either text or context_filter

What it means

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.

Source

Thrown at private_gpt/components/tools/builders/summary_builder.py:130

        self._validate_context(context_filter)
        return ContextRetriever(self.content_service, context_filter)  # type: ignore

    def _create_composite_retriever(
        self,
        texts: list[str] | None = None,
        context_filter: ContextFilter | None = None,
    ) -> "Retriever":
        """Create appropriate retriever(s) based on input parameters."""
        retrievers: list[Retriever] = []

        if texts:
            retrievers.append(self._create_text_retriever(texts))

        if context_filter:
            retrievers.append(self._create_context_retriever(context_filter))

        if not retrievers:
            raise ValueError("Must provide either text or context_filter")

        return CompositeRetriever(retrievers) if len(retrievers) > 1 else retrievers[0]

    def build(
        self,
        texts: list[str] | None = None,
        context_filter: ContextFilter | None = None,
        stop_condition_fn: Callable[[str], Awaitable[bool]] | None = None,
        llm: LLM | None = None,
        timeout: float | None = None,
    ) -> SummarizeWorkflow:
        """Build a summarize workflow."""
        retriever = self._create_composite_retriever(
            texts=texts if texts else None,
            context_filter=context_filter if context_filter else None,
        )

        return SummarizeWorkflow(

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Pass at least one non-empty string in texts, or a valid context_filter with a collection.
  2. Fix upstream input routing so exactly one of the two inputs is always populated when the summary tool is invoked.
  3. If no content is available, skip calling the summary tool rather than invoking it with empty inputs.

Example fix

# before
workflow = builder.build(texts=[], context_filter=None)

# after
workflow = builder.build(texts=[long_document_text], context_filter=None)
Defensive patterns

Strategy: validation

Validate before calling

if not texts and not context_filter:
    raise ValueError("summary tool needs texts or context_filter")
workflow = builder.build(texts=texts or None, context_filter=context_filter)

Type guard

def has_summary_input(texts, context_filter) -> bool:
    return bool(texts) or context_filter is not None

Prevention

When it happens

Trigger: 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.

Common situations: 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'.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/7f15064158243639. Report an issue: GitHub.