jamiepine/voicebox · warning · HTTPException

Empty audio file.

Error message

Empty audio file.

What it means

Returned by POST /generate/import when the upload completes but `b''.join(chunks)` yields an empty byte string — i.e. the first read returned no data (empty file) or the file was zero-length. HTTP 400. This is distinct from a missing file: the upload succeeded but contained no bytes.

Source

Thrown at backend/routes/generations.py:449

            detail=f"Unsupported audio format '{suffix}'. Allowed: {sorted(IMPORT_AUDIO_EXTENSIONS)}",
        )

    chunks: list[bytes] = []
    total = 0
    while True:
        chunk = await file.read(1024 * 1024)
        if not chunk:
            break
        total += len(chunk)
        if total > IMPORT_AUDIO_MAX_BYTES:
            raise HTTPException(
                status_code=413,
                detail=f"File exceeds {IMPORT_AUDIO_MAX_BYTES // (1024 * 1024)} MB limit.",
            )
        chunks.append(chunk)
    audio_bytes = b"".join(chunks)
    if not audio_bytes:
        raise HTTPException(status_code=400, detail="Empty audio file.")

    generation_id = str(uuid.uuid4())
    target = config.get_generations_dir() / f"{generation_id}{suffix}"
    target.write_bytes(audio_bytes)

    try:
        audio, sr = load_audio(str(target))
        duration = float(len(audio) / sr) if sr else 0.0
    except Exception as decode_err:
        try:
            target.unlink()
        except OSError:
            pass
        raise HTTPException(
            status_code=400,
            detail=f"Could not decode audio: {decode_err}",
        ) from decode_err

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Check that the source file has non-zero size on the client before uploading.
  2. If the user selected an empty file by mistake, re-select the actual asset.
  3. Treat 400 'Empty audio file.' as a user-correctable input error, not a server fault.

Example fix

// before
upload(file);

// after
if (!file || file.size === 0) { alert('File is empty'); return; }
upload(file);
Defensive patterns

Strategy: validation

Validate before calling

if (!file || file.size === 0) { alert('File is empty'); return; }
await upload(file);

Type guard

function isNonEmptyFile(file) {
  return file != null && typeof file.size === 'number' && file.size > 0;
}

Try / catch

try {
  const res = await fetch('/generate/import', { method:'POST', body: form });
  if (res.status === 400) {
    const d = await res.json();
    if (/empty/i.test(d.detail)) { alert('File is empty'); return; }
  }
} catch (e) { console.error(e); }

Prevention

When it happens

Trigger: Uploading a zero-byte file; the client sends an UploadFile with an empty filename and no body; a truncated upload where the stream ends immediately.

Common situations: Placeholder/dummy file created by accident; a frontend bug that constructs an empty FormData entry; a file truncated to 0 bytes by a sync tool.

Related errors


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