babysor/MockingBird · critical · RuntimeError
kokoro-tts CLI not found.
Error message
kokoro-tts CLI not found.
What it means
RuntimeError raised by _ensure_kokoro when the kokoro-tts CLI is not on PATH. The Kokoro local TTS backend shells out to this binary for every cue, so its absence is fatal for that backend.
Solutions
- pip install kokoro-tts (or the documented package) into the active environment
- Verify: which kokoro-tts
- Or switch the timeline config's backend to noiz
- Activate the correct virtualenv before running render_timeline
Example fix
# before $ python render_timeline.py ... # backend kokoro, CLI missing # after $ pip install kokoro-tts && which kokoro-tts $ python render_timeline.py ...
Defensive patterns
Strategy: validation
Validate before calling
import shutil
if backend == 'kokoro' and not shutil.which('kokoro-tts'):
sys.exit('kokoro-tts CLI not installed; run pip install kokoro-tts') Prevention
- Install the CLI in the active venv
- Check backend availability at startup
- Fall back to noiz backend if kokoro missing
When it happens
Trigger: Selecting the kokoro backend in the timeline config without having installed the kokoro-tts CLI, or running in an environment where its install dir isn't on PATH.
Common situations: Fresh machine, virtualenv where kokoro-tts was installed in a different env, or CI container missing the tool.
Related errors
- ffmpeg not found in PATH.
- kokoro-tts failed for cue
- Package 'webrtcvad' not found. This package enables noise…
- reference_audio not found
- Reference audio not found
AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27).
Data as JSON: /api/errors/95fec2857c3b679f.
Report an issue: GitHub.
Appendix: source
Thrown at skills/speak/scripts/render_timeline.py:312
if ref_cleanup is not None:
ref_cleanup.unlink(missing_ok=True)
if resp.status_code != 200:
raise RuntimeError(
f"/text-to-speech cue {cue.index}: "
f"status={resp.status_code}, body={resp.text}"
)
out_path.write_bytes(resp.content)
dur_h = resp.headers.get("X-Audio-Duration")
return float(dur_h) if dur_h else -1.0
# ── Kokoro backend ───────────────────────────────────────────────────
def _ensure_kokoro() -> None:
if not shutil.which("kokoro-tts"):
raise RuntimeError("kokoro-tts CLI not found.")
def _kokoro_tts(
cue: Cue,
cfg: Dict[str, Any],
output_format: str,
out_path: Path,
) -> float:
with tempfile.NamedTemporaryFile(
mode="w", suffix=".txt", delete=False, encoding="utf-8"
) as tmp:
tmp.write(cue.text)
tmp_path = tmp.name
try:
cmd = ["kokoro-tts", tmp_path, str(out_path)]
voice = cfg.get("voice")
if voice:View on GitHub (pinned to 28dc5e14f1)