heygen-com/hyperframes · error
Synthesis completed but no output file was created
Error message
Synthesis completed but no output file was created
What it means
The Python synth subprocess exited zero (execFileSync returned without throwing) AND the script's own stdout was produced, yet existsSync(outputPath) is false. The library treats this as a logic/environment failure: the script claimed success but the expected WAV is not at the agreed path. The output path is passed as argv[6] to the inline synth-v2.py script, which calls sf.write(output_path, samples, sample_rate).
Source
Thrown at packages/cli/src/tts/synthesize.ts:176
// 4. Ensure output directory exists
mkdirSync(dirname(outputPath), { recursive: true });
// 5. Run synthesis
options?.onProgress?.(`Generating speech with voice ${voice} (${lang})...`);
try {
const espeakLang = ESPEAK_LANG_OVERRIDES[lang] ?? lang;
const stdout = execFileSync(
python,
[scriptPath, modelPath, voicesPath, text, voice, String(speed), outputPath, espeakLang],
{
encoding: "utf-8",
timeout: 300_000,
stdio: ["pipe", "pipe", "pipe"],
},
);
if (!existsSync(outputPath)) {
throw new Error("Synthesis completed but no output file was created");
}
// Parse the last line of stdout as JSON (in case Python printed warnings before it)
const lines = stdout.trim().split("\n");
const jsonLine = lines[lines.length - 1] ?? "";
const result: {
outputPath: string;
sampleRate: number;
durationSeconds: number;
langApplied: boolean;
} = JSON.parse(jsonLine);
return {
outputPath: result.outputPath,
sampleRate: result.sampleRate,
durationSeconds: result.durationSeconds,
langApplied: result.langApplied,
};View on GitHub (pinned to c2996c8626)
Solutions
- Delete the cached synth script so it regenerates: rm -rf ~/.cache/hyperframes/tts/synth-v2.py and rerun.
- Verify the output directory exists and is writable: `mkdir -p $(dirname <outputPath>) && touch <outputPath>`.
- Check free disk space and permissions on the output directory.
- Inspect the cached synth-v2.py to confirm line 44 is `sf.write(output_path, samples, sample_rate)` — if not, the cache is stale.
- Run the Python script manually with the same argv to see whether sf.write raises an exception the subprocess swallowed.
Example fix
# before: stale cached script from an old CLI release rm ~/.cache/hyperframes/tts/synth-v2.py # or: rm -rf ~/.cache/hyperframes/tts # then rerun; the current CLI rewrites synth-v2.py on next invoke
Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync, mkdirSync } from 'node:fs';
import { dirname } from 'node:path';
// ensure the output path is writable BEFORE spending time on synthesis
mkdirSync(dirname(outputPath), { recursive: true });
const probe = `${outputPath}.writeprobe`;
try {
require('node:fs').writeFileSync(probe, Buffer.alloc(0));
require('node:fs').unlinkSync(probe);
} catch {
throw new Error(`Output path not writable: ${outputPath}`);
} Try / catch
try {
const r = await synthesize(text, out, { voice });
if (!existsSync(r.outputPath)) throw new Error('synthesis returned but file is missing');
} catch (err) {
if (err instanceof Error && /completed but no output file/.test(err.message)) {
// clear the cached synth script and retry once
await fs.rm('~/.cache/hyperframes/tts/synth-v2.py');
return synthesize(text, out, { voice });
}
throw err;
} Prevention
- Ensure the output directory exists and is writable before calling synthesize.
- Periodically clear ~/.cache/hyperframes/tts to regenerate the synth script after CLI upgrades.
- Check free disk space before long TTS jobs.
When it happens
Trigger: The Python script wrote to a different path than the TS side checks (path translation, symlink, or a script version mismatch where SCRIPT_PATH is stale); sf.write silently failed (disk full, permission denied) but the script did not raise; outputPath points at a directory that does not exist and sf.write raised but the error was swallowed; a custom model override wrote elsewhere.
Common situations: Stale cached synth script (~/.cache/hyperframes/tts/synth-v2.py from an older CLI) that used a different output convention; outputPath on a read-only or out-of-space filesystem; a race where a cleanup hook removed the file between sf.write and the existsSync check; Windows path quoting issues in argv passing a malformed output_path to Python.
Related errors
- Speech was generated but metadata could not be read. Check t
- Speech synthesis failed${detail}
- Python 3 is required for text-to-speech. Install Python 3.10
- The kokoro-onnx package is not installed. Run: pip install k
- [build-zip] chrome-headless-shell cache missing at ${baseDir
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/6efb5a00070e8b35.
Report an issue: GitHub.