HKUDS/DeepTutor · warning · ManimRenderError
Image mode code must only contain YON_IMAGE anchor blocks.
Error message
Image mode code must only contain YON_IMAGE anchor blocks.
What it means
Raised by _extract_text_like when FileTypeRouter.decode_bytes throws while decoding a text-like file (.txt, .md, .py, etc.). Marked 'pragma: no cover' because decode_bytes is designed never to raise (it falls back across encodings), so hitting this indicates an unexpected decoding-layer failure.
Source
Thrown at deeptutor/agents/math_animator/renderer.py:93
code_path=code_path, scene_name=scene_name, quality=quality, save_last_frame=False
)
video_file = self._find_rendered_file(".mp4")
target_name = slugify_filename(f"{self.turn_id}-{scene_name}.mp4", f"{self.turn_id}.mp4")
artifact_path = self.artifacts_dir / target_name
artifact_path.write_bytes(video_file.read_bytes())
await self._emit_progress(f"Saved rendered video as {artifact_path.name}.")
return self._build_artifact(artifact_path, "video", "video/mp4", "Animation video")
async def _render_image_blocks(self, *, code: str, quality: str) -> list[RenderedArtifact]:
matches = list(YON_IMAGE_PATTERN.finditer(code))
if not matches:
raise ManimRenderError(
"Image mode requires code blocks wrapped in ### YON_IMAGE_n_START ### / END ###."
)
residual = YON_IMAGE_PATTERN.sub("", code).strip()
if residual:
raise ManimRenderError("Image mode code must only contain YON_IMAGE anchor blocks.")
artifacts: list[RenderedArtifact] = []
for idx, match in enumerate(matches, start=1):
block_code = match.group(2).strip()
block_path = self.source_dir / f"image_block_{idx:02d}.py"
block_path.write_text(block_code, encoding="utf-8")
scene_name = self._extract_scene_name(block_code)
await self._emit_progress(
f"Rendering image block {idx}/{len(matches)} with scene `{scene_name}`."
)
await self._run_manim(
code_path=block_path,
scene_name=scene_name,
quality=quality,
save_last_frame=True,
)
image_file = self._find_rendered_file(".png")
artifact_path = self.artifacts_dir / f"image-{idx:02d}.png"View on GitHub (pinned to 3e82f13042)
Solutions
- Inspect the raw bytes (hexdump) to identify the actual encoding/corruption
- Ensure FileTypeRouter.decode_bytes fallbacks are intact if you forked the class
- Rename/re-classify the file if it is actually binary with a text extension
Example fix
// before
text = _extract_text_like(data, "weird.txt") # raises
// after
text = data.decode("utf-8", errors="replace") # manual tolerant decode as last resort Defensive patterns
Strategy: try-catch
Validate before calling
try:
FileTypeRouter.decode_bytes(data)
except Exception:
data = data.decode("utf-8", errors="replace").encode("utf-8") # sanitize Try / catch
except CorruptDocumentError as e:
if "failed to decode text" in str(e):
text = data.decode("utf-8", errors="replace") Prevention
- Treat text files as untrusted bytes; use replace-on-error decoding as a last resort
When it happens
Trigger: Bytes that defeat every fallback encoding in FileTypeRouter.decode_bytes — extremely malformed byte sequences or a decode implementation that raises a non-UnicodeDecodeError (e.g. MemoryError or a LookupError for an unknown codec).
Common situations: Essentially unreachable in normal use; would surface only after changes to FileTypeRouter or pathological binary payloads mislabeled with text extensions.
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/8f32d80a9d57fa3d.
Report an issue: GitHub.