heygen-com/hyperframes · error · ProxyBakeError

Unable to bake required browser media proxies (${summary})

Error message

Unable to bake required browser media proxies (${summary})

What it means

Thrown as a ProxyBakeError when one or more browser-hostile codec video files (HEVC, ProRes, AV1, etc.) could not be transcoded into browser-compatible proxy files during publish. Published pages are static with no server-side proxy negotiation, so hostile codecs must be pre-baked. Each failure is collected into a manifest.failed array; if any entry failed, publish is aborted with a structured summary rather than silently shipping an unplayable asset.

Source

Thrown at packages/cli/src/utils/publishProxyBake.ts:134

        const proxyPath = await waitForProxy(
          resolveProxy(absProjectDir, absoluteSourcePath, proxyVariantFor(facts)),
          TRANSCODE_TIMEOUT_MS,
        );
        const archivePath = `${PROXY_ARCHIVE_PREFIX}/${basename(proxyPath)}`;
        fileContents.set(archivePath, await readFile(proxyPath));
        proxyByAbsolutePath.set(absoluteSourcePath, archivePath);
        manifest.proxied.push(pathname);
      } catch (err) {
        const reason = err instanceof ProxyTranscodeError ? err.message : String(err);
        manifest.failed.push({ path: pathname, error: reason });
      }
    }),
  );

  manifest.proxied.sort();
  manifest.skippedAlpha.sort();
  manifest.failed.sort((a, b) => a.path.localeCompare(b.path));
  if (manifest.failed.length > 0) throw new ProxyBakeError(manifest);
  if (proxyByAbsolutePath.size === 0) return manifest;

  for (const [entryPath, content] of htmlEntries) {
    const { document } = parseHTML(content.toString("utf-8"));
    const referrerAbsDir = resolve(absProjectDir, dirname(entryPath));
    const modified = rewriteHtmlAttributes(
      document,
      referrerAbsDir,
      entryPath,
      (rawValue) => {
        const cleaned = cleanAssetUrl(rawValue);
        if (!cleaned || isRemoteOrInlineUrl(cleaned)) return null;
        // Resolve the raw attribute value the same way the scan did
        // (rewriteAssetPath to root-relative, then decodeUrlPathVariants via
        // resolveLocalAssetCandidates) so percent-encoded and root-absolute
        // srcs match the map keys the scan produced.
        const rootRelativeSrc = rewriteAssetPath(entryPath, cleaned, (path) =>
          existsSync(resolve(absProjectDir, path)),

View on GitHub (pinned to c2996c8626)

Solutions

  1. Check the manifest summary in the error — it lists each failed path and the specific transcode error reason.
  2. Ensure ffmpeg is installed and accessible (run hyperframes check) — the proxy transcoder depends on it.
  3. Pre-convert hostile-codec videos to H.264/AAC MP4 manually before publishing to bypass the bake step entirely.
  4. If a specific file is the problem, replace or re-encode it locally and re-run publish.

Example fix

// before: <video src="intro.mov"></video> (ProRes — bake fails)
// after: pre-convert to H.264 and reference the MP4 instead
//   ffmpeg -i intro.mov -c:v libx264 -c:a aac intro.mp4
//   <video src="intro.mp4"></video>
Defensive patterns

Strategy: validation

Validate before calling

import { scanProjectMediaCodecMap } from "@hyperframes/studio-server/media-codec-map";

// Scan for hostile codecs before publish to pre-warn the user
async function checkHostileCodecs(projectDir: string, html: string): Promise<string[]> {
  const codecMap = await scanProjectMediaCodecMap(projectDir, [{ html, compSrcPath: "index.html" }]);
  return Object.entries(codecMap)
    .filter(([, facts]) => facts.browserHostile)
    .map(([pathname]) => pathname);
}

Try / catch

import { ProxyBakeError } from "./publishProxyBake.js";

try {
  await bakeProxies(fileContents, projectDir);
} catch (err) {
  if (err instanceof ProxyBakeError) {
    for (const f of err.manifest.failed) {
      console.error(`Failed to proxy ${f.path}: ${f.error}`);
    }
    // Option: skip baking and publish with original files (risk: unplayable in some browsers)
  } else throw err;
}

Prevention

When it happens

Trigger: A <video src> in the composition references a local file with a browser-hostile codec; the proxy transcoder (running via the studio-server transcoder) times out after TRANSCODE_TIMEOUT_MS, crashes, or the source file is unreadable. The catch block records the reason and, after all transcodes settle, throws if manifest.failed is non-empty.

Common situations: The transcoder ffmpeg/FFmpeg is missing or an incompatible version; the source video is corrupted or has an unusual codec profile; running publish in a CI environment without the studio-server's transcoder dependencies installed; a very large 4K HEVC file exceeding the transcode timeout.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/c0b1f71bade3705c. Report an issue: GitHub.