jamiepine/voicebox · error · ValueError

Invalid manifest.json: missing version

Error message

Invalid manifest.json: missing version

What it means

After JSON-parsing manifest.json, the importer requires a 'version' key — it's used to pick the right schema/migration path. Absence is treated as corrupt or unsupported. Raised before the 'profile' key is read.

Source

Thrown at backend/services/export_import.py:154

    """
    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")
            
            # Get unique profile name
            original_name = profile_data.get("name", "Imported Profile")
            unique_name = _get_unique_profile_name(original_name, db)
            
            # Create profile
            profile_create = VoiceProfileCreate(

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Re-export with the current exporter (it always writes version: "1.0").
  2. If constructing manually, set manifest.version = "1.0".
  3. Don't strip version when editing manifests.

Example fix

// before
{"profile": {"name": "x"}, "has_avatar": false}

// after
{"version": "1.0", "profile": {"name": "x", "description": "...", "language": "en"}, "has_avatar": false}
Defensive patterns

Strategy: validation

Validate before calling

import io, json, zipfile

def manifest_has_version(file_bytes) -> bool:
    with zipfile.ZipFile(io.BytesIO(file_bytes)) as z:
        return "version" in json.loads(z.read("manifest.json"))

Type guard

def is_v1_manifest(m) -> bool:
    return isinstance(m, dict) and m.get("version") == "1.0" and "profile" in m

Try / catch

try:
    await import_profile_from_zip(file_bytes, db)
except ValueError as e:
    if "missing version" in str(e):
        # not a supported archive
        ...
    raise

Prevention

When it happens

Trigger: Hand-authored manifest without version; a manifest from an unknown producer; a manifest stripped during editing.

Common situations: Cross-version import where an older/newer format omitted version; manual archive construction; partially-rewritten manifest.

Related errors


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