{"record":{"id":"0e9f04e126998248","repo":"heygen-com/hyperframes","slug":"unsupported-output-extension-ext-use-webm-v","errorCode":null,"errorMessage":"Unsupported output extension: ${ext}. Use .webm (VP9 alpha), .mov (ProRes 4444), or .png.","messagePattern":"Unsupported output extension: (.+?)\\. Use \\.webm \\(VP9 alpha\\), \\.mov \\(ProRes 4444\\), or \\.png\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/background-removal/pipeline.ts","lineNumber":91,"sourceCode":"  format: OutputFormat;\n}\n\nconst VIDEO_EXTENSIONS = new Set([\".mp4\", \".mov\", \".webm\", \".mkv\", \".avi\"]);\nconst IMAGE_EXTENSIONS = new Set([\".jpg\", \".jpeg\", \".png\", \".webp\"]);\n\ninterface MediaInfo {\n  width: number;\n  height: number;\n  fps: number;\n  frameCount: number;\n}\n\nexport function inferOutputFormat(outputPath: string): OutputFormat {\n  const ext = extname(outputPath).toLowerCase();\n  if (ext === \".webm\") return \"webm\";\n  if (ext === \".mov\") return \"mov\";\n  if (ext === \".png\") return \"png\";\n  throw new Error(\n    `Unsupported output extension: ${ext}. Use .webm (VP9 alpha), .mov (ProRes 4444), or .png.`,\n  );\n}\n\nexport function inferInputKind(inputPath: string): \"video\" | \"image\" {\n  const ext = extname(inputPath).toLowerCase();\n  if (VIDEO_EXTENSIONS.has(ext)) return \"video\";\n  if (IMAGE_EXTENSIONS.has(ext)) return \"image\";\n  throw new Error(\n    `Unsupported input: ${ext}. Use a video (mp4/mov/webm/mkv/avi) or image (jpg/png/webp).`,\n  );\n}\n\ninterface EngineMetadata {\n  width: number;\n  height: number;\n  fps: number;\n  durationSeconds: number;","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/background-removal/pipeline.ts#L73-L109","documentation":"Thrown by inferOutputFormat when the output path's extension is not one of .webm, .mov, or .png (case-insensitive). The background-removal pipeline only produces alpha-capable outputs: VP9-with-alpha (.webm), ProRes 4444 (.mov), or a single RGBA still (.png). Formats without an alpha channel (.mp4, .avi, .mkv) are rejected here because the matte cannot be represented. Called by resolveRenderTargets at the start of render, before any ffmpeg spawn.","triggerScenarios":"Passing an outputPath ending in .mp4, .avi, .mkv, .gif, or with no extension; an uppercase extension is handled (lowercased) but .MP4 is still rejected as unsupported. Also fires for backgroundOutputPath if its extension isn't .webm/.mov.","commonSituations":"Defaulting the output to .mp4 (the common video format) without realizing background removal needs alpha; a user typing .mov for input and .mp4 for output; missing extension from a path built by string concatenation.","solutions":["Use .webm for browser-targeted alpha video, .mov for editing round-trips (ProRes 4444), or .png for a single still.","Do NOT use .mp4 — H.264/H.265 have no standardized alpha channel.","If a matte-free output is acceptable, run the source through a standard transcode instead of background removal.","Ensure backgroundOutputPath (if set) is .webm or .mov, not .png."],"exampleFix":"// before\nrender({ inputPath: 'clip.mp4', outputPath: 'out.mp4' }); // throws\n\n// after\nrender({ inputPath: 'clip.mp4', outputPath: 'out.webm' }); // VP9 alpha","handlingStrategy":"validation","validationCode":"import { extname } from 'node:path';\nconst ALPHA_OUTPUTS = new Set(['.webm', '.mov', '.png']);\nfunction assertAlphaOutput(outputPath: string): void {\n  if (!ALPHA_OUTPUTS.has(extname(outputPath).toLowerCase())) {\n    throw new Error(`output must be .webm/.mov/.png, got ${extname(outputPath)}`);\n  }\n}","typeGuard":"import { extname } from 'node:path';\nconst isAlphaOutput = (p: string): boolean =>\n  ['.webm', '.mov', '.png'].includes(extname(p).toLowerCase());","tryCatchPattern":null,"preventionTips":["Default background-removal outputs to .webm (browser alpha) or .mov (editor alpha).","Never use .mp4 — it has no alpha channel.","If a backgroundOutputPath is set, ensure it is .webm or .mov (not .png)."],"tags":["background-removal","output-format","alpha","validation","ffmpeg"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}