heygen-com/hyperframes · error

Speech synthesis failed${detail}

Error message

Speech synthesis failed${detail}

What it means

The catch-all at the end of synthesize()'s try block. Fires when execFileSync threw a non-SyntaxError (i.e. the Python process exited non-zero, was killed by the 300s timeout, or could not be spawned), OR when JSON.parse threw but the output file does NOT exist (so it is not the [244] path). detail appends the last 500 chars of stderr when present on the thrown error object, so the message usually carries the Python traceback.

Source

Thrown at packages/cli/src/tts/synthesize.ts:209

      sampleRate: result.sampleRate,
      durationSeconds: result.durationSeconds,
      langApplied: result.langApplied,
    };
  } catch (err: unknown) {
    // If the error is our own JSON parse failure but the file was created,
    // re-throw with a clearer message rather than returning fabricated data
    if (err instanceof SyntaxError && existsSync(outputPath)) {
      throw new Error(
        "Speech was generated but metadata could not be read. Check the output file manually.",
      );
    }

    let detail = "";
    if (err && typeof err === "object" && "stderr" in err) {
      const stderr = String(err.stderr).trim();
      if (stderr) detail = `\n${stderr.slice(-500)}`;
    }
    throw new Error(`Speech synthesis failed${detail}`);
  }
}

View on GitHub (pinned to c2996c8626)

Solutions

  1. Read the detail (last 500 chars of stderr) — it carries the Python traceback; address the specific exception it names.
  2. Re-download the model: delete the cached Kokoro model and voices under the HF cache dir and rerun (ensureModel/ensureVoices will re-fetch).
  3. Install espeak-ng system-wide if the error mentions phonemization for a non-English lang.
  4. For timeout (300s) on long text, synthesize shorter segments and concatenate.
  5. Run the cached synth-v2.py manually with the same argv to reproduce the Python-side error outside the library.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  return await synthesize(text, out, { voice });
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Speech synthesis failed')) {
    // err.message includes the last 500 chars of the Python stderr — inspect it
    console.error('TTS subprocess error:', err.message);
    // retry with shorter text, a different voice, or after re-downloading the model
  }
  throw err;
}

Prevention

When it happens

Trigger: Python raised during model load (corrupt/missing Kokoro model file), during phonemization (unsupported voice id, espeak-ng missing for non-English lang), OOM during inference, the 300_000ms execFileSync timeout fired, or the model/voices paths passed in argv do not exist. Any unhandled Python exception produces a non-zero exit → this error.

Common situations: First-run model download was interrupted leaving a truncated .onnx; voice id not present in voices.bin; espeak-ng not installed on the system for Mandarin/other non-English langs; very long input text exceeding memory; a GPU/CPU mismatch in onnxruntime causing a crash at inference.

Related errors


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