HKUDS/DeepTutor · error · RuntimeError

math_animator requires optional dependencies. Install with `

Error message

math_animator requires optional dependencies. Install with `pip install 'deeptutor[math-animator]'` or `pip install -r requirements/math-animator.txt`.

What it means

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.

Source

Thrown at deeptutor/agents/math_animator/capability.py:43

            "concept_design",
            "code_generation",
            "code_retry",
            "summary",
            "render_output",
        ],
        tools_used=[],
        cli_aliases=["animate"],
        request_schema=get_capability_request_schema("math_animator"),
        config_defaults={
            "output_mode": "video",
            "quality": "medium",
            "style_hint": "",
        },
    )

    async def run(self, context: UnifiedContext, stream: StreamBus) -> None:
        if importlib.util.find_spec("manim") is None:
            raise RuntimeError(
                "math_animator requires optional dependencies. "
                "Install with `pip install 'deeptutor[math-animator]'` "
                "or `pip install -r requirements/math-animator.txt`."
            )
        from deeptutor.agents.math_animator.pipeline import MathAnimatorPipeline
        from deeptutor.agents.math_animator.request_config import (
            validate_math_animator_request_config,
        )
        from deeptutor.services.llm.config import get_llm_config

        llm_config = get_llm_config()
        request_config = validate_math_animator_request_config(context.config_overrides)
        usage = UsageTracker(model=getattr(llm_config, "model", None))
        i18n = StatusI18n(self.name, context.language, module="math_animator")
        pipeline = MathAnimatorPipeline(
            api_key=llm_config.api_key,
            base_url=llm_config.base_url,
            api_version=llm_config.api_version,

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Convert .xls to .xlsx (LibreOffice or pandas+xlrd) before ingestion
  2. Remove workbook protection/re-save from Excel
  3. If encrypted, decrypt with msoffcrypto-tool first

Example fix

// before
text = extract_text_from_bytes(data, filename="sheet.xlsx")  # actually .xls

// after
import msoffcrypto, io
f = msoffcrypto.OfficeFile(io.BytesIO(data)); f.load_key(password=pw)
buf = io.BytesIO(); f.write(buf)
text = extract_text_from_bytes(buf.getvalue(), filename="sheet.xlsx")
Defensive patterns

Strategy: validation

Validate before calling

def is_ooxml(data: bytes) -> bool:
    return data[:2] == b"PK"

if not is_ooxml(data):
    convert_xls_to_xlsx(fn)

Try / catch

except CorruptDocumentError as e:
    if "failed to open XLSX" in str(e):
        try_decrypt_with_msoffcrypto(data) or convert_and_retry(fn)

Prevention

When it happens

Trigger: 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.

Common situations: Excel exports from old tools, password-protected workbooks, interrupted uploads.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/3b2b2778f43ca4eb. Report an issue: GitHub.