heygen-com/hyperframes · warning
Speech was generated but metadata could not be read. Check…
Error message
Speech was generated but metadata could not be read. Check the output file manually.
What it means
Synthesis actually succeeded — the WAV exists at outputPath — but JSON.parse on the last line of the Python stdout threw a SyntaxError. The inline script prints a JSON metadata object as its final line; if Python emitted a warning, traceback fragment, or print AFTER that line (or if the JSON was malformed), parsing fails. The library deliberately surfaces a clearer message rather than re-throwing the raw SyntaxError or fabricating metadata.
Solutions
- The audio file was created — use it directly; the metadata (sampleRate, durationSeconds) can be re-derived from the WAV header if needed.
- Set PYTHONWARNINGS=ignore to suppress warnings that may print to stdout after the JSON line.
- Inspect the cached synth-v2.py: confirm the json.dumps print is the absolute last statement with no trailing code.
- Capture and read the Python stdout yourself to see what came after the JSON line and report the noise source.
Defensive patterns
Strategy: fallback
Try / catch
try {
return await synthesize(text, out, { voice });
} catch (err) {
if (err instanceof Error && /metadata could not be read/.test(err.message) && existsSync(out)) {
// synthesis succeeded — derive metadata from the WAV header instead of failing
return { outputPath: out, sampleRate: readWavSampleRate(out), durationSeconds: readWavDuration(out), langApplied: false };
}
throw err;
} Prevention
- Set PYTHONWARNINGS=ignore to keep warnings off stdout where they can follow the JSON line.
- If you control the pipeline, treat the existing WAV as success even when metadata is unreadable.
- Pin kokoro-onnx to a version known to print only the JSON line to stdout.
When it happens
Trigger: A Python warning (e.g. from torch/onnxruntime) printed to stdout AFTER the JSON line; the script printed a deprecation warning without a trailing newline ordering; a newer kokoro-onnx prints a progress/info line after the JSON; multi-line stdout where the 'last line' heuristic grabs a partial JSON fragment.
Common situations: User upgraded kokoro-onnx and the new version logs to stdout; PYTHONUNBUFFERED or a logging config that emits to stdout; a NumPy/torch ABI warning that prints at import time after the metadata print; stderr/stdout interleaving under some CI log capturers.
Related errors
- Speech synthesis failed
- Synthesis completed but no output file was created
- Python 3 is required for text-to-speech. Install Python…
- The kokoro-onnx package is not installed. Run: pip install…
- At least one grade candidate is required
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/2b032a093303f569.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/tts/synthesize.ts:199
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,
};
} 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)