{"record":{"id":"9fb0f275fb2c749d","repo":"HKUDS/DeepTutor","slug":"image-mode-requires-code-blocks-wrapped-in-yon","errorCode":null,"errorMessage":"Image mode requires code blocks wrapped in ### YON_IMAGE_n_START ### / END ###.","messagePattern":"Image mode requires code blocks wrapped in ### YON_IMAGE_n_START ### / END ###\\.","errorType":"exception","errorClass":"ManimRenderError","httpStatus":null,"severity":"error","filePath":"deeptutor/agents/math_animator/renderer.py","lineNumber":87,"sourceCode":"        )\n\n    async def _render_video(self, *, code_path: Path, quality: str) -> RenderedArtifact:\n        scene_name = self._extract_scene_name(code_path.read_text(encoding=\"utf-8\"))\n        await self._emit_progress(f\"Launching Manim scene `{scene_name}`.\")\n        await self._run_manim(\n            code_path=code_path, scene_name=scene_name, quality=quality, save_last_frame=False\n        )\n        video_file = self._find_rendered_file(\".mp4\")\n        target_name = slugify_filename(f\"{self.turn_id}-{scene_name}.mp4\", f\"{self.turn_id}.mp4\")\n        artifact_path = self.artifacts_dir / target_name\n        artifact_path.write_bytes(video_file.read_bytes())\n        await self._emit_progress(f\"Saved rendered video as {artifact_path.name}.\")\n        return self._build_artifact(artifact_path, \"video\", \"video/mp4\", \"Animation video\")\n\n    async def _render_image_blocks(self, *, code: str, quality: str) -> list[RenderedArtifact]:\n        matches = list(YON_IMAGE_PATTERN.finditer(code))\n        if not matches:\n            raise ManimRenderError(\n                \"Image mode requires code blocks wrapped in ### YON_IMAGE_n_START ### / END ###.\"\n            )\n\n        residual = YON_IMAGE_PATTERN.sub(\"\", code).strip()\n        if residual:\n            raise ManimRenderError(\"Image mode code must only contain YON_IMAGE anchor blocks.\")\n\n        artifacts: list[RenderedArtifact] = []\n        for idx, match in enumerate(matches, start=1):\n            block_code = match.group(2).strip()\n            block_path = self.source_dir / f\"image_block_{idx:02d}.py\"\n            block_path.write_text(block_code, encoding=\"utf-8\")\n            scene_name = self._extract_scene_name(block_code)\n            await self._emit_progress(\n                f\"Rendering image block {idx}/{len(matches)} with scene `{scene_name}`.\"\n            )\n            await self._run_manim(\n                code_path=block_path,","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/agents/math_animator/renderer.py#L69-L105","documentation":"Raised by _extract_pptx when python-pptx fails to open the presentation and the raw-OOXML fallback recovers no text. Mirrors the XLSX/DOCX pattern: primary parser error + empty fallback → CorruptDocumentError with the underlying message.","triggerScenarios":"A .ppt file renamed to .pptx; a corrupted or truncated pptx zip; a presentation where python-pptx fails on malformed slide XML and no fallback <a:t> text exists.","commonSituations":"Old PowerPoint decks renamed rather than converted; decks from third-party exporters with non-standard XML; partial uploads.","solutions":["Convert legacy .ppt via LibreOffice to .pptx","Re-export/re-save the deck in PowerPoint","Repair the zip container (unzip + rezip) if truncated"],"exampleFix":"// before\ntext = extract_text_from_bytes(data, filename=\"deck.pptx\")  # actually .ppt\n\n// after\nsubprocess.run([\"soffice\",\"--headless\",\"--convert-to\",\"pptx\",\"deck.ppt\"], check=True)\ntext = extract_text_from_bytes(Path(\"deck.pptx\").read_bytes(), filename=\"deck.pptx\")","handlingStrategy":"validation","validationCode":"def is_ooxml(data: bytes) -> bool:\n    return data[:2] == b\"PK\"\n\nif not is_ooxml(data):\n    convert_ppt_to_pptx(fn)","typeGuard":null,"tryCatchPattern":"except CorruptDocumentError as e:\n    if \"failed to open PPTX\" in str(e):\n        soffice_convert(fn, \"pptx\") and retry","preventionTips":["Convert .ppt decks before upload","Verify integrity of pptx zips after transfer"],"tags":["pptx","python-pptx","corruption","document-extraction"],"backgroundTag":"corrupt-pptx-parse","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}