babysor/MockingBird · error · ValueError
No segments to mix.
Error message
No segments to mix.
What it means
ValueError raised by mix_all when the list of input segment paths is empty. The final timeline mix needs at least one rendered segment to build an ffmpeg amix filter graph.
Solutions
- Fail loudly on the first per-cue synthesis error instead of continuing with an empty list
- Check why zero segments were produced (API failures, missing voices) before the mix step
- Add a sanity check: if len(segments) != len(cues): warn
Example fix
# before
mix_all(segments, out, total_ms)
# after
if not segments:
raise RuntimeError("all cue syntheses failed; see logs above")
mix_all(segments, out, total_ms) Defensive patterns
Strategy: validation
Validate before calling
assert segments, 'no segments produced; check per-cue logs'
Prevention
- Abort on first cue failure instead of collecting nothing
- Compare len(segments) to len(cues) before mix
- Log skipped cues explicitly
When it happens
Trigger: All per-cue TTS segments failed or were filtered out before mixing, or parse_srt produced cues but synthesis yielded zero output files.
Common situations: A loop swallows per-cue synthesis errors and continues, leaving inputs empty; or a voice-map misconfiguration maps every cue to a skipped backend.
Related errors
- ffmpeg failed: \n
- ffprobe failed on
- Both increase only and decrease only are set
- Cue : either voice_id or reference_audio required.
- duration must be in range (0, 36] seconds
AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27).
Data as JSON: /api/errors/59d4a8304fe633dd.
Report an issue: GitHub.
Appendix: source
Thrown at skills/speak/scripts/render_timeline.py:184
filters.append(f"atempo={r:.6f}")
_run_ff([
"ffmpeg", "-y", "-i", str(inp),
"-af", ",".join(filters),
"-t", f"{target_ms / 1000.0:.3f}", str(outp),
])
def delay_segment(inp: Path, outp: Path, start_ms: int) -> None:
_run_ff([
"ffmpeg", "-y", "-i", str(inp),
"-af", f"adelay={start_ms}:all=1", str(outp),
])
def mix_all(inputs: List[Path], outp: Path, total_ms: int) -> None:
if not inputs:
raise ValueError("No segments to mix.")
cmd = ["ffmpeg", "-y"]
for p in inputs:
cmd += ["-i", str(p)]
cmd += [
"-filter_complex",
f"amix=inputs={len(inputs)}:duration=longest:dropout_transition=0",
"-t", f"{total_ms / 1000.0:.3f}", str(outp),
]
_run_ff(cmd)
# ── Noiz backend ─────────────────────────────────────────────────────
def _noiz_emotion_enhance(
base_url: str, api_key: str, text: str, timeout: int
) -> str:
import requests # noqa: delayed import so kokoro path doesn't need requestsView on GitHub (pinned to 28dc5e14f1)