{"record":{"id":"3b2b2778f43ca4eb","repo":"HKUDS/DeepTutor","slug":"math-animator-requires-optional-dependencies-inst","errorCode":null,"errorMessage":"math_animator requires optional dependencies. Install with `pip install 'deeptutor[math-animator]'` or `pip install -r requirements/math-animator.txt`.","messagePattern":"math_animator requires optional dependencies\\. Install with `pip install 'deeptutor\\[math-animator\\]'` or `pip install -r requirements/math-animator\\.txt`\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"deeptutor/agents/math_animator/capability.py","lineNumber":43,"sourceCode":"            \"concept_design\",\n            \"code_generation\",\n            \"code_retry\",\n            \"summary\",\n            \"render_output\",\n        ],\n        tools_used=[],\n        cli_aliases=[\"animate\"],\n        request_schema=get_capability_request_schema(\"math_animator\"),\n        config_defaults={\n            \"output_mode\": \"video\",\n            \"quality\": \"medium\",\n            \"style_hint\": \"\",\n        },\n    )\n\n    async def run(self, context: UnifiedContext, stream: StreamBus) -> None:\n        if importlib.util.find_spec(\"manim\") is None:\n            raise RuntimeError(\n                \"math_animator requires optional dependencies. \"\n                \"Install with `pip install 'deeptutor[math-animator]'` \"\n                \"or `pip install -r requirements/math-animator.txt`.\"\n            )\n        from deeptutor.agents.math_animator.pipeline import MathAnimatorPipeline\n        from deeptutor.agents.math_animator.request_config import (\n            validate_math_animator_request_config,\n        )\n        from deeptutor.services.llm.config import get_llm_config\n\n        llm_config = get_llm_config()\n        request_config = validate_math_animator_request_config(context.config_overrides)\n        usage = UsageTracker(model=getattr(llm_config, \"model\", None))\n        i18n = StatusI18n(self.name, context.language, module=\"math_animator\")\n        pipeline = MathAnimatorPipeline(\n            api_key=llm_config.api_key,\n            base_url=llm_config.base_url,\n            api_version=llm_config.api_version,","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/agents/math_animator/capability.py#L25-L61","documentation":"Raised by _extract_xlsx when openpyxl fails to load the workbook AND the raw-OOXML fallback also finds no text. The openpyxl error message is embedded, and the exception is chained. It means the bytes are not a readable XLSX and no worksheet text could be salvaged.","triggerScenarios":"A legacy .xls (OLE2) file renamed to .xlsx; a truncated zip; an encrypted workbook that openpyxl cannot open and whose fallback paths contain no shared strings or sheet data.","commonSituations":"Excel exports from old tools, password-protected workbooks, interrupted uploads.","solutions":["Convert .xls to .xlsx (LibreOffice or pandas+xlrd) before ingestion","Remove workbook protection/re-save from Excel","If encrypted, decrypt with msoffcrypto-tool first"],"exampleFix":"// before\ntext = extract_text_from_bytes(data, filename=\"sheet.xlsx\")  # actually .xls\n\n// after\nimport msoffcrypto, io\nf = msoffcrypto.OfficeFile(io.BytesIO(data)); f.load_key(password=pw)\nbuf = io.BytesIO(); f.write(buf)\ntext = extract_text_from_bytes(buf.getvalue(), filename=\"sheet.xlsx\")","handlingStrategy":"validation","validationCode":"def is_ooxml(data: bytes) -> bool:\n    return data[:2] == b\"PK\"\n\nif not is_ooxml(data):\n    convert_xls_to_xlsx(fn)","typeGuard":null,"tryCatchPattern":"except CorruptDocumentError as e:\n    if \"failed to open XLSX\" in str(e):\n        try_decrypt_with_msoffcrypto(data) or convert_and_retry(fn)","preventionTips":["Check PK magic bytes; treat OLE2 as legacy .xls","Decrypt protected workbooks with msoffcrypto-tool before ingest"],"tags":["xlsx","openpyxl","corruption","document-extraction"],"backgroundTag":"corrupt-xlsx-parse","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}