jamiepine/voicebox · error · ValueError

ZIP archive missing samples.json

Error message

ZIP archive missing samples.json

What it means

Same validation pass as error 233: samples.json (the filename-to-reference-text mapping) must be present at the ZIP root. Without it the importer can't associate each audio file with its reference text, so it rejects before parsing.

Source

Thrown at backend/services/export_import.py:148

        
    Returns:
        Created profile
        
    Raises:
        ValueError: If ZIP is invalid or missing required files
    """
    zip_buffer = io.BytesIO(file_bytes)
    
    try:
        with zipfile.ZipFile(zip_buffer, 'r') as zip_file:
            # Validate ZIP structure
            namelist = zip_file.namelist()
            
            if "manifest.json" not in namelist:
                raise ValueError("ZIP archive missing manifest.json")
            
            if "samples.json" not in namelist:
                raise ValueError("ZIP archive missing samples.json")
            
            # Read manifest
            manifest_data = json.loads(zip_file.read("manifest.json"))
            
            if "version" not in manifest_data:
                raise ValueError("Invalid manifest.json: missing version")
            
            if "profile" not in manifest_data:
                raise ValueError("Invalid manifest.json: missing profile")
            
            profile_data = manifest_data["profile"]
            
            # Read samples mapping
            samples_data = json.loads(zip_file.read("samples.json"))
            
            if not isinstance(samples_data, dict):
                raise ValueError("Invalid samples.json: must be a dictionary")
            

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Re-export the profile to obtain a complete archive.
  2. If rebuilding manually, include a samples.json object mapping each wav filename to its reference text.
  3. Don't strip entries from exported ZIPs.

Example fix

# before — samples.json removed from the zip
await import_profile_from_zip(stripped_zip, db)

# after — include samples.json at the zip root:
# { "abc.wav": "hello world", "def.wav": "second sample" }
Defensive patterns

Strategy: validation

Validate before calling

import io, zipfile

def has_samples_json(file_bytes) -> bool:
    with zipfile.ZipFile(io.BytesIO(file_bytes)) as z:
        return "samples.json" in z.namelist()

Try / catch

try:
    await import_profile_from_zip(file_bytes, db)
except ValueError as e:
    if "missing samples.json" in str(e):
        # reject, ask for a complete archive
        ...
    raise

Prevention

When it happens

Trigger: A manifest-only archive, a partially-assembled export, or a hand-edited ZIP from which samples.json was stripped.

Common situations: Editing an exported ZIP and dropping samples.json; third-party archive lacking the mapping; truncated upload.

Related errors


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