heygen-com/hyperframes · error · AudioFxRenderError
Audio FX produced no samples for track ${options.trackId}
Error message
Audio FX produced no samples for track ${options.trackId} What it means
Thrown when the browser-side audio FX render returns zero output planes or an empty first plane. After decoding the base64-encoded Float32 arrays back from the page, the code checks outPlanes.length === 0 or outPlanes[0]?.length === 0. A successful render must produce at least one non-empty sample plane; silence or an empty result indicates the FX chain consumed all input without producing output.
Source
Thrown at packages/engine/src/services/audioFxRender.ts:274
},
[
planes.map((plane) =>
Buffer.from(plane.buffer, plane.byteOffset, plane.length * 4).toString("base64"),
),
sampleRate,
JSON.stringify(chain),
] as [string[], number, string],
)) as string[];
// 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
- Log the chainJson and the number of input planes/samples to verify the chain is well-formed.
- Test the FX chain in isolation in a browser with the same input WAV to see if output is genuinely empty.
- Check enabledAudioFxNodes() output for unexpected or misconfigured nodes.
- If a gain/gate effect is intentional, ensure it doesn't reduce output to exactly zero-length — a silence plane should still have sample-count matching input.
Defensive patterns
Strategy: validation
Try / catch
try {
await applyAudioFxChain(inputWav, chain, outWav, opts);
} catch (err) {
if (err instanceof AudioFxRenderError && err.message.includes('produced no samples')) {
// test chain in isolation, check for silencing nodes
}
throw err;
} Prevention
- Validate the FX chain configuration before rendering: ensure no node has an extreme gain/gate that eliminates all samples.
- Test FX chains with a short clip in a browser console before full render.
- Log input sample count and compare with output to catch silent chains early.
When it happens
Trigger: The page.evaluate call to api.render(channelB64, rate, chainJson) resolved successfully, but the returned array is empty or contains only empty Float32Arrays. This can happen if the FX runtime has a bug in its output encoding, if the chainJson describes a chain that produces zero-length output, or if a gain/node silences the signal to exactly zero samples.
Common situations: A custom AudioFxNode has a bug that returns an empty buffer. The chain JSON is malformed enough to pass validation but produces no output. The base64 round-trip between page and Node lost data (though that more likely causes a different decode error). A gate/expander node with extreme settings eliminates all samples.
Related errors
- Audio file too large for headless analysis (${mb}MB > ${MAX_
- --remote-debugging-port must be an integer between 1 and 655
- Unsupported file type: ${ext}
- Unknown effect type: ${type}
- Node ${i} has unknown effect type: ${String(node.type)}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/4ade32bb0bd3b1be.
Report an issue: GitHub.