can1357/oh-my-pi · error · Error

VHS failed to render the gallery screenshot${detail ? `: ${d

Error message

VHS failed to render the gallery screenshot${detail ? `: ${detail.slice(-600)}` : ""}

What it means

renderChunk invokes the resolved `vhs` binary on a generated .tape file and expects exit code 0 plus a non-empty output PNG. If either check fails it throws with the last 600 characters of VHS's captured stderr/stdout, after cleaning up the temporary tape/ansi/gif files in a finally block.

Source

Thrown at packages/coding-agent/src/cli/gallery-screenshot.ts:140

	await Bun.write(
		tapePath,
		buildTape({
			gifPath,
			outPng: args.outPng,
			ansiPath,
			widthPx,
			heightPx,
			font: args.font,
			fontSize: args.fontSize,
			themeJson: args.themeJson,
		}),
	);

	try {
		const result = await Bun.$`${args.vhs} ${tapePath}`.quiet().nothrow();
		if (result.exitCode !== 0 || !(await Bun.file(args.outPng).exists())) {
			const detail = result.stderr.toString().trim() || result.stdout.toString().trim();
			throw new Error(`VHS failed to render the gallery screenshot${detail ? `: ${detail.slice(-600)}` : ""}`);
		}
	} finally {
		await Promise.all([
			fs.promises.rm(ansiPath, { force: true }),
			fs.promises.rm(tapePath, { force: true }),
			fs.promises.rm(gifPath, { force: true }),
		]);
	}
}

interface TapeArgs {
	gifPath: string;
	outPng: string;
	ansiPath: string;
	widthPx: number;
	heightPx: number;
	font: string;
	fontSize: number;

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the detail suffix in the message — it contains VHS's own error output; fix the underlying issue it reports
  2. Install/refresh fonts required for the configured screenshot font (`options.font`)
  3. Upgrade VHS to the latest version (`brew upgrade vhs`) and retry
  4. Run in an environment with a usable PTY (e.g. use `script -c` in CI containers) and confirm the output directory is writable
Defensive patterns

Strategy: try-catch

Validate before calling

import { $which } from "@oh-my-pi/pi-utils";
const vhs = $which("vhs");
if (!vhs) throw new Error("vhs not installed");
if (!process.stdout.isTTY && process.env.CI) console.warn("headless render may fail without PTY/fonts");

Try / catch

try {
  const pngs = await captureGalleryScreenshots(sections, opts);
} catch (err) {
  const detail = err instanceof Error ? err.message : String(err);
  if (detail.startsWith("VHS failed to render")) {
    logger.error("VHS render failed — check VHS output in message", { detail: detail.slice(-600) });
    // fall back or rethrow with VHS's own detail
  } else throw err;
}

Prevention

When it happens

Trigger: VHS exits non-zero or fails to produce outPng — e.g. invalid tape directives, a PTY/font problem in headless environments, missing fonts, or out-of-memory/timeout during rendering.

Common situations: Running screenshots in CI containers without a working PTY or fonts; tape generation producing directives the installed VHS version rejects; disk space or permission problems preventing the PNG from being written.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/5a62d1788ae2d9c8. Report an issue: GitHub.