{"record":{"id":"ba319c5b8257f811","repo":"HKUDS/DeepTutor","slug":"sectionarchitect-produced-no-subsections-in-outlin","errorCode":null,"errorMessage":"SectionArchitect produced no subsections in outline pass.","messagePattern":"SectionArchitect produced no subsections in outline pass\\.","errorType":"exception","errorClass":"GenerationFailure","httpStatus":null,"severity":"error","filePath":"deeptutor/book/blocks/section.py","lineNumber":103,"sourceCode":"        # when the cached sweep returned nothing.\n        rag = await optional_rag_lookup(\n            query=f\"{chapter_title}: {focus_topic}\",\n            ctx=ctx,\n        )\n\n        # ── Pass 1: outline ───────────────────────────────────────────\n        outline = await self._make_outline(\n            ctx=ctx,\n            chapter_title=chapter_title,\n            chapter_summary=chapter_summary,\n            objectives=objectives,\n            focus_topic=focus_topic,\n            section_role=section_role,\n            target_words=target_words,\n            rag_context=rag.text,\n        )\n        if not outline.get(\"subsections\"):\n            raise GenerationFailure(\"SectionArchitect produced no subsections in outline pass.\")\n\n        # ── Pass 2: fill subsections in parallel ─────────────────────\n        relevant_chunks: list[SourceChunk] = []\n        try:\n            relevant_chunks = ctx.relevant_chunks(focus_topic, limit=8)\n        except Exception:  # noqa: BLE001\n            relevant_chunks = []\n\n        subs = outline[\"subsections\"]\n        coros = [\n            self._fill_subsection(\n                ctx=ctx,\n                chapter_title=chapter_title,\n                section_focus=focus_topic,\n                outline_intro=outline.get(\"intro\", \"\"),\n                sub=sub,\n                chunks=relevant_chunks,\n            )","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/book/blocks/section.py#L85-L121","documentation":"The section block runs a two-pass flow: SectionArchitect first produces an outline dict, and pass 2 fills subsections. If outline.get('subsections') is empty/missing, the outline pass failed to deliver structure and GenerationFailure is raised before any content generation.","triggerScenarios":"Calling section _generate when SectionArchitect returns an outline without a 'subsections' key, with an empty list, or a payload where subsections parses to nothing (e.g. outline is a refusal string parsed to {}).","commonSituations":"LLM returns JSON missing 'subsections' due to prompt/schema drift; subsections under a different key ('sections'); overly constrained target_words or odd section_role confusing the architect; model too weak to follow the outline schema; rag_context empty leading to degenerate outline.","solutions":["Log the raw outline payload to see whether subsections is absent, empty, or under another key","Retry — outline omissions are often transient","Tighten the architect prompt to enforce the exact JSON schema with a minimum subsection count","Use a stronger model and ensure focus_topic/target_words/section_role inputs are sane"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"def outline_has_subsections(outline) -> bool:\n    return isinstance(outline, dict) and isinstance(outline.get('subsections'), list) and len(outline['subsections']) > 0","tryCatchPattern":"try:\n    return await section_block.generate(ctx)\nexcept GenerationFailure as exc:\n    if 'no subsections' in str(exc):\n        return await section_block.generate(ctx)  # outline passes are flaky\n    raise","preventionTips":["Enforce the outline JSON schema with a minimum subsection count in the architect prompt","Use a model with reliable structured output for the outline pass","Ensure focus_topic/target_words/section_role inputs are well-formed before generation"],"tags":["section","outline","llm-output","empty-response","generation"],"backgroundTag":"llm-output-schema-mismatch","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}