jamiepine/voicebox · error · ValueError

Invalid reference audio: {error_msg}

Error message

Invalid reference audio: {error_msg}

What it means

Raised by add_profile_sample() when validate_and_load_reference_audio() rejects the uploaded audio. The wrapped error_msg is one of: 'Audio too short (minimum 2.0 seconds)', 'Audio too long (maximum 30.0 seconds)', 'Audio is too quiet or silent', or 'Error validating audio: {load exception}'. Duration/silence checks run on the preprocessed waveform, so slight clipping is tolerated but genuinely silent or out-of-range audio is rejected.

Source

Thrown at backend/services/profiles.py:229

        audio_path: Path to temporary audio file
        reference_text: Transcript of audio
        db: Database session

    Returns:
        Created sample
    """
    import asyncio

    profile = db.query(DBVoiceProfile).filter_by(id=profile_id).first()
    if not profile:
        raise ValueError(f"Profile {profile_id} not found")

    # Validate and load audio in a single pass, off the event loop
    is_valid, error_msg, audio, sr = await asyncio.to_thread(
        validate_and_load_reference_audio, audio_path
    )
    if not is_valid:
        raise ValueError(f"Invalid reference audio: {error_msg}")

    sample_id = str(uuid.uuid4())
    profile_dir = config.get_profiles_dir() / profile_id
    profile_dir.mkdir(parents=True, exist_ok=True)

    dest_path = profile_dir / f"{sample_id}.wav"
    await asyncio.to_thread(save_audio, audio, str(dest_path), sr)

    db_sample = DBProfileSample(
        id=sample_id,
        profile_id=profile_id,
        audio_path=config.to_storage_path(dest_path),
        reference_text=reference_text,
    )

    db.add(db_sample)

    profile.updated_at = datetime.utcnow()

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Trim/record the clip to between 2 and 30 seconds of clean speech.
  2. Re-export from the source at a standard format (WAV/MP3) and confirm it plays back with audible volume.
  3. Inspect the specific error_msg: 'too short'/'too long'/'too quiet' point to content; 'Error validating audio' points to decoding — re-encode the file or install the missing decoder.

Example fix

# before - 1s silent clip uploaded
# after - export a 5-15s clean speech wav
ffmpeg -i in.mp3 -t 10 -ar 24000 -ac 1 out.wav
Defensive patterns

Strategy: validation

Validate before calling

from ..utils.audio import validate_and_load_reference_audio

# pre-check the file before calling add_profile_sample
ok, msg, _audio, _sr = validate_and_load_reference_audio(audio_path)
if not ok:
    raise HTTPException(400, f"reference audio rejected: {msg}")
# duration limits: 2.0s..30.0s, RMS >= 0.01 after preprocessing

Type guard

import os

def is_likely_valid_audio(path: str) -> bool:
    return os.path.exists(path) and os.path.getsize(path) > 0 and path.lower().endswith((".wav", ".mp3", ".flac", ".ogg", ".m4a"))

Try / catch

try:
    await add_profile_sample(profile_id, audio_path, ref_text, db)
except ValueError as e:
    if str(e).startswith("Invalid reference audio"):
        raise HTTPException(400, str(e))  # surface the specific reason to the client
    raise

Prevention

When it happens

Trigger: Uploading a clip shorter than 2s or longer than 30s; an essentially silent track (RMS below 0.01 after preprocessing); a corrupt or unreadable file; an unsupported container/codec that load_audio cannot decode.

Common situations: User records a very short snippet; uploads background music or a near-empty track; file truncated during transfer; wrong file sent (e.g. a .wav header on a non-audio payload); ffmpeg/backend decoder missing for the codec.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/dcdae722fab56b48. Report an issue: GitHub.