heygen-com/hyperframes · error · AudioFxRenderError

Audio FX input is missing: ${inputWav}

Error message

Audio FX input is missing: ${inputWav}

What it means

Thrown by applyAudioFxChain() when existsSync(inputWav) returns false — the WAV file that the FX chain is supposed to process does not exist on disk. The comment above the function explains this is a fatal error, not a soft warning, because silently rendering the dry signal produces a mix that sounds plausible but is not what the author configured.

Source

Thrown at packages/engine/src/services/audioFxRender.ts:202

/**
 * Run a chain over `inputWav`, writing `outputWav`. Resolves to the path to use
 * downstream: `outputWav` when the chain did something, `inputWav` untouched
 * when the chain was empty.
 *
 * Failure is fatal to the caller rather than a soft per-track warning: quietly
 * rendering the dry signal ships a mix that sounds plausible and is not what
 * the author set up.
 */
export async function applyAudioFxChain(
  inputWav: string,
  chain: HfAudioFxChain,
  outputWav: string,
  options: { trackId: string; signal?: AbortSignal },
): Promise<string> {
  if (enabledAudioFxNodes(chain).length === 0) return inputWav;
  if (!existsSync(inputWav)) {
    throw new AudioFxRenderError(`Audio FX input is missing: ${inputWav}`);
  }

  const { samples, sampleRate, channels } = readWav(inputWav);
  const planes = deinterleave(samples, channels);

  // Audio processing needs no GPU or special capture mode; a plain sandboxed
  // browser is enough, and the lease pool reuses one across tracks.
  const lease = await acquireBrowser([
    "--no-sandbox",
    "--autoplay-policy=no-user-gesture-required",
  ]);
  const hostDir = mkdtempSync(join(tmpdir(), "hf-fx-host-"));
  try {
    if (options.signal?.aborted) {
      throw new AudioFxRenderError(`Audio FX cancelled for track ${options.trackId}`);
    }
    const page = await lease.browser.newPage();
    try {

View on GitHub (pinned to c2996c8626)

Solutions

  1. Check that the upstream render step for this track completed and wrote the WAV: verify with fs.existsSync(path) before calling applyAudioFxChain.
  2. Inspect the path for typos, wrong tmpdir, or missing directory components.
  3. If rendering in a serverless/container environment, ensure the temp volume is shared between the render and FX steps.
  4. Log the trackId and resolved path in the producer's track scheduler to catch mapping bugs early.

Example fix

// before
await applyAudioFxChain(inputWav, chain, outWav, opts);

// after
import { existsSync } from 'fs';
if (!existsSync(inputWav)) {
  throw new Error(`Track ${opts.trackId}: upstream render did not produce ${inputWav}`);
}
await applyAudioFxChain(inputWav, chain, outWav, opts);
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, statSync } from 'fs';

function validateInputWav(path: string): void {
  if (!existsSync(path)) {
    throw new Error(`Input WAV not found: ${path}. Check upstream render step.`);
  }
  const stat = statSync(path);
  if (stat.size < 44) {
    throw new Error(`Input WAV too small (${stat.size} bytes): ${path}`);
  }
}

validateInputWav(inputWav);

Try / catch

try {
  await applyAudioFxChain(inputWav, chain, outWav, opts);
} catch (err) {
  if (err instanceof AudioFxRenderError && err.message.includes('input is missing')) {
    // re-run upstream render, or mark track as failed
  }
  throw err;
}

Prevention

When it happens

Trigger: applyAudioFxChain(inputWav, chain, outputWav, options) is called after enabledAudioFxNodes(chain).length > 0 confirms there are active FX nodes, but the inputWav path does not resolve to an existing file. The check runs before readWav().

Common situations: The upstream capture/render step that should have produced the track WAV failed or was skipped. A temp-file path was garbage-collected or used a different tmpdir than expected. The trackId-to-path mapping in the producer pipeline has a bug. A render was interrupted between scheduling and execution.

Related errors


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