{"record":{"id":"7ab1e82c237a566d","repo":"can1357/oh-my-pi","slug":"omp-gallery-screenshot-requires-vhs-which-is","errorCode":null,"errorMessage":"`omp gallery --screenshot` requires VHS, which is not installed. Install it (e.g. `brew install vhs`, or see https://github.com/charmbracelet/vhs) and retry.","messagePattern":"`omp gallery --screenshot` requires VHS, which is not installed\\. Install it \\(e\\.g\\. `brew install vhs`, or see https://github\\.com/charmbracelet/vhs\\) and retry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/gallery-screenshot.ts","lineNumber":64,"sourceCode":"\t/**\n\t * Output destination. When omitted, PNGs land in a fresh temp directory.\n\t * With multiple images the path is suffixed (`name-01.png`, `name-02.png`).\n\t */\n\tout?: string;\n}\n\n/**\n * Capture the gallery sections as one or more PNGs and return their absolute\n * paths. Tall galleries are split across images so no single capture exceeds\n * the terminal-canvas height limit.\n */\nexport async function captureGalleryScreenshots(\n\tsections: GallerySection[],\n\toptions: GalleryScreenshotOptions,\n): Promise<string[]> {\n\tconst vhs = $which(\"vhs\");\n\tif (!vhs) {\n\t\tthrow new Error(\n\t\t\t\"`omp gallery --screenshot` requires VHS, which is not installed. \" +\n\t\t\t\t\"Install it (e.g. `brew install vhs`, or see https://github.com/charmbracelet/vhs) and retry.\",\n\t\t);\n\t}\n\n\tconst font = options.font ?? DEFAULT_SCREENSHOT_FONT;\n\tconst fontSize = options.fontSize ?? DEFAULT_SCREENSHOT_FONT_SIZE;\n\tconst cellHeight = fontSize * Math.max(LINE_HEIGHT, 1) * CELL_HEIGHT_RATIO;\n\tconst cellWidth = fontSize * CELL_WIDTH_RATIO;\n\tconst rowBudget = Math.max(40, Math.floor((MAX_IMAGE_HEIGHT_PX - 2 * PADDING) / cellHeight) - 2);\n\tconst chunks = chunkGallerySections(sections, rowBudget);\n\tconst themeJson = buildVhsTheme();\n\n\tconst baseDir = options.out\n\t\t? path.dirname(path.resolve(options.out))\n\t\t: fs.mkdtempSync(path.join(os.tmpdir(), \"omp-gallery-\"));\n\tawait fs.promises.mkdir(baseDir, { recursive: true });\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/gallery-screenshot.ts#L46-L82","documentation":"captureGalleryScreenshots renders gallery sections via VHS (charmbracelet/vhs), which must be on PATH. Before doing any work it probes for the binary with $which(\"vhs\") and throws this instructional error when missing, so the failure is a clear setup message rather than a confusing spawn ENOENT later.","triggerScenarios":"Running `omp gallery --screenshot` on a machine where the `vhs` executable is not installed or not on PATH (minimal CI image, fresh dev machine, PATH lacking the install prefix).","commonSituations":"Fresh macOS/Linux setup without brew-installed vhs; CI containers missing the dependency; nix/venv style environments where PATH is restricted; vhs installed but under a name not on PATH.","solutions":["Install VHS: `brew install vhs` (see https://github.com/charmbracelet/vhs for other platforms)","Verify with `which vhs` that the binary is on PATH; fix PATH if installed elsewhere","In CI, add a step installing vhs before running the screenshot command"],"exampleFix":"// before (fails)\nomp gallery --screenshot\n// after\nbrew install vhs\nomp gallery --screenshot","handlingStrategy":"validation","validationCode":"import { $which } from \"@oh-my-pi/pi-utils\";\nif (!$which(\"vhs\")) {\n  throw new Error(\"vhs is required for gallery screenshots: brew install vhs\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install vhs as part of machine/CI setup before running screenshot commands","Add a preflight `command -v vhs` check in scripts that call --screenshot","Document the vhs dependency in the project README/setup docs"],"tags":["cli","missing-dependency","environment","external-tool"],"backgroundTag":"missing-dependency","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}