HKUDS/DeepTutor · error · GenerationFailure
no questions generated
Error message
no questions generated
What it means
Even though QuizGenerator succeeded, the block's _extract_questions(summary) extracted zero usable questions from the returned summary dict — either the summary lacked question data or every question failed extraction. The guard then raises GenerationFailure('no questions generated').
Source
Thrown at deeptutor/book/blocks/quiz.py:72
user_message=topic,
active_capability="deep_question",
knowledge_bases=[effective_kb] if effective_kb else [],
language=ctx.language,
),
user_message=topic,
num_questions=max(1, int(num_questions or 1)),
difficulty=difficulty,
question_types=question_types,
stream=get_book_bus(ctx.book_id),
)
summary = dict(result.get("summary") or {})
except Exception as exc:
logger.warning(f"QuizGenerator failed: {exc}", exc_info=True)
raise GenerationFailure(f"quiz generation failed: {exc}") from exc
questions = self._extract_questions(summary)
if not questions:
raise GenerationFailure("no questions generated")
return (
{"questions": questions, "topic": topic},
[],
{
"completed": summary.get("completed", 0),
"failed": summary.get("failed", 0),
"kb": ctx.primary_kb,
},
)
@staticmethod
def _extract_questions(summary: dict[str, Any]) -> list[dict[str, Any]]:
results = summary.get("results") or []
if not isinstance(results, list):
return []
out: list[dict[str, Any]] = []
for item in results:View on GitHub (pinned to 3e82f13042)
Solutions
- Log the summary dict and compare its question structure against _extract_questions' expectations
- Align the QuizGenerator version with the block, or update the extractor key/shape handling
- Retry with clearer quiz parameters (non-empty question_types)
- If the generator legitimately produced no questions, prompt for at least N questions
Defensive patterns
Strategy: validation
Validate before calling
summary = result.get('summary') or {}
qs = summary.get('questions') or []
assert qs, 'quiz summary has no questions; aborting before block guard' Type guard
def summary_has_questions(summary: dict) -> bool:
return isinstance(summary, dict) and isinstance(summary.get('questions'), list) and len(summary['questions']) > 0 Try / catch
try:
return await quiz_block.generate(ctx)
except GenerationFailure as exc:
if 'no questions generated' in str(exc):
return await quiz_block.generate(ctx) # retry once
raise Prevention
- Pin QuizGenerator and block versions together so the summary shape matches
- Pre-check summary['questions'] when calling the generator directly
- Request a minimum question count in quiz parameters
When it happens
Trigger: Calling quiz _generate when result['summary'] is empty/None (generator returned dict without questions) or its question entries don't match the shape _extract_questions expects, yielding an empty list.
Common situations: QuizGenerator returns summary with questions under a different key after a version change; questions stored as non-dict entries that extraction skips; LLM produced no questions but the generator didn't fail; completed counts present but questions list empty.
Related errors
- LLM returned no deep-dive suggestions.
- LLM did not return any flashcards.
- quiz generation failed: {exc}
- SectionArchitect produced no subsections in outline pass.
- animation generation failed: {exc}
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/9ddfdd02c4355028.
Report an issue: GitHub.