HKUDS/DeepTutor · error · ManimRenderError

Generated code does not define a renderable Manim Scene clas

Error message

Generated code does not define a renderable Manim Scene class.

What it means

DocumentTooLargeError raised when a single EPUB member's uncompressed file_size exceeds _EPUB_MAX_MEMBER_BYTES. Guards against decompressing one gigantic file (classic zip-bomb member) before reading it.

Source

Thrown at deeptutor/agents/math_animator/renderer.py:226

    def _find_rendered_file(self, suffix: str) -> Path:
        # Manim stores many transient chunks under ``partial_movie_files``.
        # We only want the final exported artifact for the scene.
        matches = [
            path
            for path in self.media_dir.rglob(f"*{suffix}")
            if "partial_movie_files" not in path.parts
        ]
        if not matches:
            matches = list(self.media_dir.rglob(f"*{suffix}"))
        if not matches:
            raise ManimRenderError(f"Rendered {suffix} artifact not found.")
        return max(matches, key=lambda path: path.stat().st_mtime)

    @staticmethod
    def _extract_scene_name(code: str) -> str:
        match = SCENE_PATTERN.search(code)
        if not match:
            raise ManimRenderError("Generated code does not define a renderable Manim Scene class.")
        return match.group(1)

    def _build_artifact(
        self,
        artifact_path: Path,
        artifact_type: str,
        content_type: str,
        label: str,
    ) -> RenderedArtifact:
        rel_path = artifact_path.resolve().relative_to(self.path_service.user_data_dir.resolve())
        return RenderedArtifact(
            type=artifact_type,
            filename=artifact_path.name,
            url=f"/api/outputs/{rel_path.as_posix()}",
            content_type=content_type,
            label=label,
        )

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Split or compress oversized assets, or remove the huge member if it's an image not needed for text extraction
  2. Re-export the EPUB with image downscaling (ebook-convert --enable-heuristics / image compression)
  3. Enforce per-file upload limits before ingestion

Example fix

// before
text = extract_text_from_bytes(data, filename="bomb.epub")  # raises

// after
import zipfile
zf = zipfile.ZipFile(io.BytesIO(data))
keep = [i.filename for i in zf.infolist() if i.file_size < 50_000_000]
# rebuild epub without the oversized member, then extract
Defensive patterns

Strategy: validation

Validate before calling

import zipfile, io
zf = zipfile.ZipFile(io.BytesIO(data))
if any(i.file_size > 100_000_000 for i in zf.infolist()):
    reject(fn, "contains oversized member")

Try / catch

except DocumentTooLargeError as e:
    if "member" in str(e) and "too large" in str(e):
        strip_oversized_members_and_retry(data)

Prevention

When it happens

Trigger: An EPUB containing a single multi-hundred-MB HTML/image asset; crafted archive whose header declares an oversized member.

Common situations: EPUBs embedding raw high-res images or uncompressed media; malicious archives targeting extraction pipelines.

Related errors


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