jamiepine/voicebox · warning · HTTPException
File exceeds {IMPORT_AUDIO_MAX_BYTES // (1024 * 1024)} MB li
Error message
File exceeds {IMPORT_AUDIO_MAX_BYTES // (1024 * 1024)} MB limit. What it means
Returned by POST /generate/import when the cumulative uploaded byte total exceeds IMPORT_AUDIO_MAX_BYTES (200 * 1024 * 1024 = 200 MB). The endpoint streams the upload in 1 MB chunks and checks `total > IMPORT_AUDIO_MAX_BYTES` after each chunk, so the rejection happens mid-stream. HTTP 413 Payload Too Large.
Source
Thrown at backend/routes/generations.py:442
Designed for the story timeline so users can drop in music or other
non-TTS audio. The row points at a singleton "Imported Audio" profile
so the existing generation/story plumbing keeps working unchanged."""
suffix = Path(file.filename or "").suffix.lower()
if suffix not in IMPORT_AUDIO_EXTENSIONS:
raise HTTPException(
status_code=400,
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()View on GitHub (pinned to 51f49dea19)
Solutions
- Compress or trim the audio to under 200 MB before uploading (downsample, convert to mp3/flac).
- If larger imports are genuinely needed, raise IMPORT_AUDIO_MAX_BYTES in backend/routes/generations.py AND raise the reverse proxy body limit (e.g. nginx client_max_body_size) to match.
- Validate file size client-side before the upload starts to avoid a wasted partial transfer.
- For very large media, split into segments.
Example fix
// before
upload(file);
// after
const MAX = 200 * 1024 * 1024;
if (file.size > MAX) { alert(`File exceeds ${MAX/1048576} MB`); return; }
upload(file); Defensive patterns
Strategy: validation
Validate before calling
const MAX = 200 * 1024 * 1024;
if (file.size > MAX) { alert(`File exceeds ${MAX/1048576} MB`); return; }
await upload(file); Type guard
function withinImportLimit(file, limitBytes = 200 * 1024 * 1024) {
return file && typeof file.size === 'number' && file.size <= limitBytes;
} Try / catch
try {
const res = await fetch('/generate/import', { method:'POST', body: form });
if (res.status === 413) { alert('File too large'); return; }
} catch (e) { console.error(e); } Prevention
- Check file.size before upload to avoid wasted bandwidth.
- If raising the limit server-side, also raise the reverse proxy body limit.
- Compress long-form audio before importing.
When it happens
Trigger: Uploading an audio file larger than 200 MB; uploading a file that is nominally under the limit but the streamed chunks push the running total past it on the last read.
Common situations: Long-form music mixes or uncompressed WAV masters exceeding 200 MB; a reverse proxy (nginx) with its own client_max_body_size set lower intercepting first; browser uploading a folder-compressed blob.
Related errors
- Unsupported audio format '{suffix}'. Allowed: {sorted(IMPORT
- Empty audio file.
- Could not decode audio: {decode_err}
- File too large. Maximum size is {MAX_FILE_SIZE / (1024 * 102
- HTTP ${res.status}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/771bfce535a9dac7.
Report an issue: GitHub.