heygen-com/hyperframes · error · AudioFxRenderError
Audio FX failed for track ${options.trackId}: ${(err as Erro
Error message
Audio FX failed for track ${options.trackId}: ${(err as Error).message} What it means
Catch-all wrapper thrown by the outer try/catch in applyAudioFxChain() for any error that is NOT already an AudioFxRenderError. The inner catch checks instanceof AudioFxRenderError and re-throws those as-is; everything else (browser crashes, page.evaluate exceptions, network errors, unexpected throws) gets wrapped with the trackId and original message for diagnostics. The finally clause still releases the browser lease and removes the temp directory.
Source
Thrown at packages/engine/src/services/audioFxRender.ts:283
// byteOffset and byteLength matter: Node pools small allocations, so a
// short payload decodes into an 8 KiB pool and a view over the whole
// ArrayBuffer would read kilobytes of unrelated memory at the wrong length.
const outPlanes = rendered.map((b64) => {
const buf = Buffer.from(b64, "base64");
return new Float32Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
});
if (outPlanes.length === 0 || (outPlanes[0]?.length ?? 0) === 0) {
throw new AudioFxRenderError(`Audio FX produced no samples for track ${options.trackId}`);
}
writeWav(outputWav, interleave(outPlanes), sampleRate, outPlanes.length);
return outputWav;
} finally {
await page.close().catch(() => undefined);
}
} catch (err) {
if (err instanceof AudioFxRenderError) throw err;
throw new AudioFxRenderError(
`Audio FX failed for track ${options.trackId}: ${(err as Error).message}`,
);
} finally {
rmSync(hostDir, { recursive: true, force: true });
await lease.release().catch(() => undefined);
}
}
export type { HfAudioFxChain };
View on GitHub (pinned to c2996c8626)
Solutions
- Read the appended original message: 'Audio FX failed for track X: <original>' — the original message is the real diagnostic.
- If 'Target closed' / 'Browser disconnected': check Chrome memory limits, add --disable-dev-shm-usage or increase container memory.
- If 'Evaluation failed': debug the runtime script in a standalone browser.
- Add retry logic around applyAudioFxChain for transient browser crashes, with a fresh browser lease per attempt.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await applyAudioFxChain(inputWav, chain, outWav, opts);
} catch (err) {
if (err instanceof AudioFxRenderError && err.message.includes('Audio FX failed for track')) {
// extract inner message, check for browser crash / target closed
const inner = err.message.split(': ').slice(1).join(': ');
if (inner.includes('Target closed') || inner.includes('disconnected')) {
// retry with a fresh browser lease
}
}
throw err;
} Prevention
- Monitor Chrome process memory; add --disable-dev-shm-usage in memory-constrained containers.
- Implement retry with a fresh browser lease for transient crashes.
- Log the full inner error message for post-mortem diagnostics.
When it happens
Trigger: Any unhandled exception during page setup, script injection, page.evaluate, or WAV writing that isn't already an AudioFxRenderError. The original error's message is appended to give context. Common inner errors: 'Target closed' (browser crashed), 'Evaluation failed' (JS error in page), 'Navigation timeout'.
Common situations: Headless Chrome crashed (OOM, segfault) during FX processing. The page navigated or closed unexpectedly. A JS error inside the evaluate callback (not the __HF_AUDIO_FX check, which is caught separately) propagated. Puppeteer protocol error due to browser disconnect.
Related errors
- audio FX runtime failed to load
- Failed to load @puppeteer/browsers: ${cause} Fix: run `npm i
- Audio FX produced no samples for track ${options.trackId}
- Neither puppeteer nor puppeteer-core found
- beginFrame screenshot returned ${bytes.length} bytes after $
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/d8406121966eb501.
Report an issue: GitHub.