jamiepine/voicebox · error · HTTPException
{e}
Error message
{e} What it means
Returned by POST /history/import when `export_import.import_generation_from_zip(content, db)` raises a ValueError, caught and re-raised as HTTP 400 with the exception's message. ValueErrors from this layer signal expected, client-correctable problems: malformed ZIP structure, missing manifest, schema mismatch, or duplicate id collision.
Source
Thrown at backend/routes/history.py:60
async def import_generation(
file: UploadFile = File(...),
db: Session = Depends(get_db),
):
"""Import a generation from a ZIP archive."""
MAX_FILE_SIZE = 50 * 1024 * 1024
content = await file.read()
if len(content) > MAX_FILE_SIZE:
raise HTTPException(
status_code=400, detail=f"File too large. Maximum size is {MAX_FILE_SIZE / (1024 * 1024)}MB"
)
try:
result = await export_import.import_generation_from_zip(content, db)
return result
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/history/failed")
async def clear_failed_generations(db: Session = Depends(get_db)):
"""Delete every generation with status='failed'. Used by the UI's 'Clear failed' button (#410)."""
count = await history.delete_failed_generations(db)
return {"deleted": count}
@router.get("/history/{generation_id}", response_model=models.HistoryResponse)
async def get_generation(
generation_id: str,
db: Session = Depends(get_db),
):
"""Get a generation by ID."""
result = (View on GitHub (pinned to 51f49dea19)
Solutions
- Read the error message — ValueErrors here are user-facing and explain the specific ZIP problem.
- Only import ZIPs produced by GET /history/{id}/export for this app version.
- If the manifest schema changed across versions, re-export from the source version after upgrading.
- Open the ZIP locally and verify it contains the expected manifest + audio files before retrying.
Example fix
// before: upload any zip
upload(myZip);
// after: only export-produced zips
if (!file.name.endsWith('.voicebox.zip')) { alert('Use an exported generation ZIP'); return; }
upload(file); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate it's an exported voicebox zip before uploading
if (!file.name.endsWith('.voicebox.zip')) { alert('Use an exported generation ZIP'); return; }
await upload(file); Type guard
function looksLikeVoiceboxExport(file) {
return file && typeof file.name === 'string' && file.name.endsWith('.voicebox.zip');
} Try / catch
try {
const res = await fetch('/history/import', { method:'POST', body: form });
if (res.status === 400) {
const d = await res.json();
showImportError(d.detail); // carries the ValueError reason
return;
}
} catch (e) { console.error(e); } Prevention
- Only import ZIPs produced by the export endpoint for this version.
- Inspect the manifest inside the ZIP if the error is unclear.
- Re-export from the source version after upgrades.
When it happens
Trigger: Uploading a file that is not a valid .voicebox.zip export; the ZIP is missing its manifest/metadata file; the manifest's schema doesn't match the expected version; importing a generation whose id already exists (if the layer enforces uniqueness).
Common situations: Uploading an arbitrary ZIP instead of one produced by the /history/{id}/export endpoint; importing an export from a newer app version whose manifest format changed; corrupt download of the export.
Related errors
- File too large. Maximum size is {MAX_FILE_SIZE / (1024 * 102
- Unsupported audio format '{suffix}'. Allowed: {sorted(IMPORT
- Empty audio file.
- Generation has no audio file
- ZIP archive missing manifest.json
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/0e0023ba713cf57b.
Report an issue: GitHub.