babysor/MockingBird · error · ValueError

duration must be in range (0, 36] seconds

Error message

duration must be in range (0, 36] seconds

What it means

ValueError raised by synthesize() when the optional duration parameter is outside the API-supported range. The Noiz /text-to-speech endpoint only accepts durations greater than 0 and at most 36 seconds; this is a client-side pre-validation of that constraint.

Source

Thrown at skills/speak/scripts/noiz_tts.py:70

def synthesize(
    base_url: str,
    api_key: str,
    text: str,
    voice_id: Optional[str],
    reference_audio: Optional[Path],
    output_format: str,
    speed: float,
    emo: Optional[str],
    target_lang: Optional[str],
    similarity_enh: bool,
    save_voice: bool,
    duration: Optional[float],
    timeout: int,
    out_path: Path,
) -> float:
    if duration is not None and not (0 < duration <= 36):
        raise ValueError("duration must be in range (0, 36] seconds")
    url = f"{base_url.rstrip('/')}/text-to-speech"
    data: Dict[str, str] = {
        "text": text,
        "output_format": output_format,
        "speed": str(speed),
    }
    if voice_id:
        data["voice_id"] = voice_id
    if emo:
        data["emo"] = emo
    if target_lang:
        data["target_lang"] = target_lang
    if similarity_enh:
        data["similarity_enh"] = "true"
    if save_voice:
        data["save_voice"] = "true"
    if duration is not None:
        data["duration"] = str(duration)

View on GitHub (pinned to 28dc5e14f1)

Solutions

  1. Clamp duration to (0, 36] before calling synthesize
  2. Split long audio into multiple <=36s requests and concatenate
  3. Pass duration=None to let the server decide length

Example fix

# before
synthesize(..., duration=60.0)
# after
synthesize(..., duration=min(duration, 36.0))
Defensive patterns

Strategy: validation

Validate before calling

def safe_duration(d):
    if d is None: return None
    if not (0 < d <= 36):
        raise ValueError('duration must be in (0, 36]')
    return d

Type guard

def is_valid_duration(d) -> bool:
    return d is None or (isinstance(d, (int, float)) and 0 < d <= 36)

Try / catch

try:
    synthesize(...)
except ValueError as e:
    if 'duration' in str(e):
        synthesize(..., duration=None)

Prevention

When it happens

Trigger: Calling synthesize(..., duration=0), a negative duration, or duration > 36 (e.g. 60 to synthesize a minute of audio in one call).

Common situations: User passes a CLI --duration meant for long narration, or computes duration from subtitle cue timings that exceed 36s per cue.

Related errors


AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27). Data as JSON: /api/errors/a4eecf4d3de0fecf. Report an issue: GitHub.