heygen-com/hyperframes · error

Audio file too large for headless analysis (${mb}MB > ${MAX_

Error message

Audio file too large for headless analysis (${mb}MB > ${MAX_AUDIO_BYTES / 1e6}MB).

What it means

Thrown by analyzeBeatsHeadless() before any browser work when audioBytes.length exceeds MAX_AUDIO_BYTES (80 MiB). The guard exists because the audio is base64-encoded (+33% size) and shipped to the headless page over CDP; a very large file would blow CDP message limits and stall. The message reports the actual size in MB and the cap (80MB).

Source

Thrown at packages/cli/src/beats/headlessAnalyzer.ts:133

  });
  page.on("console", (m) => {
    if (m.type() === "error") pageErrors.push(m.text());
  });
  await page.setContent("<!doctype html><html><body></body></html>");
  await page.addScriptTag({ content: bundle });
  try {
    return (await page.evaluate(inPageAnalyze, b64)) as HeadlessBeatResult;
  } catch (err) {
    const detail = pageErrors.length ? ` (${pageErrors.join("; ")})` : "";
    throw new Error(`${err instanceof Error ? err.message : String(err)}${detail}`);
  }
}

/** Decode + analyze the given audio bytes in headless Chrome. */
export async function analyzeBeatsHeadless(audioBytes: Buffer): Promise<HeadlessBeatResult> {
  if (audioBytes.length > MAX_AUDIO_BYTES) {
    const mb = Math.round(audioBytes.length / 1e6);
    throw new Error(
      `Audio file too large for headless analysis (${mb}MB > ${MAX_AUDIO_BYTES / 1e6}MB).`,
    );
  }
  const bundle = await buildAnalyzerBundle();
  const { ensureBrowser } = await import("../browser/manager.js");
  const puppeteer = await import("puppeteer-core");
  const browser = await ensureBrowser();
  const chrome: Browser = await puppeteer.default.launch({
    headless: true,
    executablePath: browser.executablePath,
    args: ["--no-sandbox", "--disable-dev-shm-usage", "--autoplay-policy=no-user-gesture-required"],
  });
  try {
    const page = await chrome.newPage();
    return await detectOnPage(page, bundle, audioBytes.toString("base64"));
  } finally {
    await chrome.close();
  }

View on GitHub (pinned to c2996c8626)

Solutions

  1. Trim the audio to the section you need: `ffmpeg -i in.flac -t 180 -c:a libmp3lame -q:a 2 clip.mp3` (first 180s).
  2. Downsample/compress to MP3 or AAC to shrink the byte size while keeping beat-detection-relevant frequencies.
  3. If you need beats for a long track, analyze a representative segment and extrapolate, or raise the cap locally by editing MAX_AUDIO_BYTES if you control memory.

Example fix

# before — 200MB FLAC rejected
$ bunx hyperframes beats album.flac
# trim and compress
$ ffmpeg -i album.flac -t 300 -c:a libmp3lame -b:a 192k clip.mp3
$ bunx hyperframes beats clip.mp3
Defensive patterns

Strategy: validation

Validate before calling

const MAX = 80 * 1024 * 1024;
if (audioBytes.length > MAX) {
  throw new Error(`Audio too large (${Math.round(audioBytes.length / 1e6)}MB). Trim or compress to <= 80MB.`);
}
await analyzeBeatsHeadless(audioBytes);

Type guard

function audioWithinLimit(bytes: Buffer): boolean {
  return bytes.length <= 80 * 1024 * 1024;
}

Prevention

When it happens

Trigger: Calling analyzeBeatsHeadless(buf) where buf is a Buffer longer than 83,886,080 bytes (80*1024*1024). Typical with long mixes, podcast episodes, or lossless files (FLAC/WAV) of a few minutes.

Common situations: User runs the beats command on a 2-hour podcast WAV; a lossless FLAC that is large per minute; a full album rip passed as one file.

Related errors


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