{"record":{"id":"9ddfdd02c4355028","repo":"HKUDS/DeepTutor","slug":"no-questions-generated","errorCode":null,"errorMessage":"no questions generated","messagePattern":"no questions generated","errorType":"exception","errorClass":"GenerationFailure","httpStatus":null,"severity":"error","filePath":"deeptutor/book/blocks/quiz.py","lineNumber":72,"sourceCode":"                    user_message=topic,\n                    active_capability=\"deep_question\",\n                    knowledge_bases=[effective_kb] if effective_kb else [],\n                    language=ctx.language,\n                ),\n                user_message=topic,\n                num_questions=max(1, int(num_questions or 1)),\n                difficulty=difficulty,\n                question_types=question_types,\n                stream=get_book_bus(ctx.book_id),\n            )\n            summary = dict(result.get(\"summary\") or {})\n        except Exception as exc:\n            logger.warning(f\"QuizGenerator failed: {exc}\", exc_info=True)\n            raise GenerationFailure(f\"quiz generation failed: {exc}\") from exc\n\n        questions = self._extract_questions(summary)\n        if not questions:\n            raise GenerationFailure(\"no questions generated\")\n\n        return (\n            {\"questions\": questions, \"topic\": topic},\n            [],\n            {\n                \"completed\": summary.get(\"completed\", 0),\n                \"failed\": summary.get(\"failed\", 0),\n                \"kb\": ctx.primary_kb,\n            },\n        )\n\n    @staticmethod\n    def _extract_questions(summary: dict[str, Any]) -> list[dict[str, Any]]:\n        results = summary.get(\"results\") or []\n        if not isinstance(results, list):\n            return []\n        out: list[dict[str, Any]] = []\n        for item in results:","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/book/blocks/quiz.py#L54-L90","documentation":"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').","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"summary = result.get('summary') or {}\nqs = summary.get('questions') or []\nassert qs, 'quiz summary has no questions; aborting before block guard'","typeGuard":"def summary_has_questions(summary: dict) -> bool:\n    return isinstance(summary, dict) and isinstance(summary.get('questions'), list) and len(summary['questions']) > 0","tryCatchPattern":"try:\n    return await quiz_block.generate(ctx)\nexcept GenerationFailure as exc:\n    if 'no questions generated' in str(exc):\n        return await quiz_block.generate(ctx)  # retry once\n    raise","preventionTips":["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"],"tags":["quiz","extraction","empty-response","generation"],"backgroundTag":"llm-empty-response","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}