zylon-ai/private-gpt · error · ValueError

No summary was generated

Error message

No summary was generated

What it means

Raised when run_summary was called WITHOUT output_cls and the finished SummarizeResultEvent carries no usable summary text (summary is None, empty, or not a str). The summarization completed but produced no prose — typically an empty LLM response after the fallback chain (response.response and empty_response_fallback both empty).

Source

Thrown at private_gpt/components/workflows/others/summary.py:138

                )
            )
            result: SummarizeResultEvent = await handler

            if output_cls:
                response = result.output_obj
                if not response:
                    raise ValueError("No output object was generated")
                if not isinstance(response, BaseModel):
                    raise TypeError(
                        f"Expected output object to be a BaseModel, got {type(response)}"
                    )
                return [TextBlock(text=response.model_dump_json())]
            else:
                summary = result.summary
                summary_text = summary if isinstance(summary, str) else None

                if not summary_text:
                    raise ValueError("No summary was generated")

                return [TextBlock(text=summary_text)]
        except asyncio.CancelledError as e:
            if handler:
                await handler.cancel_run()
            raise e

    async def _generate_prompt_template(
        self,
        prompt: str | None = None,
    ) -> BasePromptTemplate:
        """Define the prompt template for summarization."""

        def messages_gen() -> Iterator[ChatMessage]:
            if prompt:
                yield ChatMessage(
                    content=prompt,
                    role=MessageRole.SYSTEM,

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Set empty_response_fallback (e.g. 'No content available to summarize') in run_summary so empty LLM responses degrade gracefully.
  2. Inspect response.response from the query engine — if consistently empty, check retriever hit counts and prompt template context.
  3. Raise max_output_tokens / check the token-limit configuration applied in execute_summarize.
  4. If you actually wanted structured output, pass output_cls so the correct branch runs.

Example fix

# before
blocks = await wf.run_summary(prompt=p)

# after
blocks = await wf.run_summary(prompt=p, empty_response_fallback="No content available to summarize.")
Defensive patterns

Strategy: fallback

Validate before calling

blocks = await wf.run_summary(
    prompt=p,
    empty_response_fallback="No content available to summarize.",
)

Type guard

def has_summary(ev: SummarizeResultEvent) -> bool:
    return isinstance(ev.summary, str) and ev.summary.strip() != ""

Try / catch

try:
    blocks = await wf.run_summary(prompt=p)
except ValueError as e:
    if 'No summary was generated' in str(e):
        blocks = [TextBlock(text='Summary unavailable.')]
    else:
        raise

Prevention

When it happens

Trigger: Query engine returns Response with response="" and no empty_response_fallback provided; LLM returns only whitespace/empty completion for the summary prompt; the workflow emitted a SummarizeResultEvent with only output_obj set while the caller asked for plain text.

Common situations: Summarizing an empty or irrelevant document set where the model answers nothing; overly strict token limits truncating output to empty; stop_condition_fn truncation paths; misconfigured prompts yielding empty 'Answer:' sections.

Related errors


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