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
- Set empty_response_fallback (e.g. 'No content available to summarize') in run_summary so empty LLM responses degrade gracefully.
- Inspect response.response from the query engine — if consistently empty, check retriever hit counts and prompt template context.
- Raise max_output_tokens / check the token-limit configuration applied in execute_summarize.
- 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
- Always pass empty_response_fallback for user-facing summary endpoints
- Monitor empty-response rates per model to catch prompt/token-budget regressions
- Assert retrieved node count > 0 before invoking summarization
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
- Audio blocks found but no audio-capable LLM provided.
- Failed to describe audio in the message.
- Failed to describe images in the message.
- Configured model does not support function calling
- No items returned from astream_structured_predict
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/24c1d10138609b2d.
Report an issue: GitHub.