jamiepine/voicebox · error · ValueError

Invalid manifest.json: missing generation.{field}

Error message

Invalid manifest.json: missing generation.{field}

What it means

Raised during generation import when manifest['generation'] is present but is missing one of the required keys text, language, or duration (export_import.py:376-379, loop over required_fields). The {field} substitution names the first missing key. These three fields populate non-nullable columns on DBGeneration.

Source

Thrown at backend/services/export_import.py:379

                raise ValueError("ZIP archive missing manifest.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 "generation" not in manifest_data:
                raise ValueError("Invalid manifest.json: missing generation data")
            
            generation_data = manifest_data["generation"]
            profile_data = manifest_data.get("profile", {})
            
            # Validate required fields
            required_fields = ["text", "language", "duration"]
            for field in required_fields:
                if field not in generation_data:
                    raise ValueError(f"Invalid manifest.json: missing generation.{field}")
            
            # Find audio file in archive
            audio_files = [f for f in namelist if f.startswith("audio/") and f.endswith(".wav")]
            if not audio_files:
                raise ValueError("No audio file found in ZIP archive")
            
            audio_file_path = audio_files[0]
            
            # Check if we should match an existing profile or create metadata
            profile_id = None
            profile_name = profile_data.get("name", "Unknown Profile")
            
            # Try to find matching profile by name
            if profile_name and profile_name != "Unknown Profile":
                existing_profile = db.query(DBVoiceProfile).filter_by(name=profile_name).first()
                if existing_profile:
                    profile_id = existing_profile.id
            

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Open manifest.json, locate generation.{field}, and add a valid value (text=str, language=ISO code like 'en', duration=float seconds).
  2. Re-export from a source instance running the same schema version.
  3. If the field genuinely does not apply, backfill a sensible default (e.g. language='en', duration=0.0) before importing.
  4. Align your fork's exporter key names with required_fields.

Example fix

// before: missing duration
{"generation":{"text":"hi","language":"en"}}
// after
{"generation":{"text":"hi","language":"en","duration":1.8}}
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED = {'text', 'language', 'duration'}

def generation_fields_present(file_bytes: bytes) -> list[str]:
    """Return the list of missing required generation fields (empty if ok)."""
    with zipfile.ZipFile(io.BytesIO(file_bytes)) as z:
        m = json.loads(z.read('manifest.json'))
    gen = m.get('generation', {})
    return [f for f in REQUIRED if f not in gen]

Type guard

def is_complete_generation(gen: object) -> bool:
    return (
        isinstance(gen, dict)
        and isinstance(gen.get('text'), str) and gen['text']
        and isinstance(gen.get('language'), str) and gen['language']
        and isinstance(gen.get('duration'), (int, float))
    )

Try / catch

try:
    result = await import_generation_from_bytes(file_bytes, db)
except ValueError as e:
    if str(e).startswith('Invalid manifest.json: missing generation.'):
        raise HTTPException(400, str(e))
    raise HTTPException(400, str(e))

Prevention

When it happens

Trigger: A generation archive exported from an older build that did not record one of these fields (e.g. language was added later); a hand-edited manifest that stripped a field; an exporter on a fork that used different key names.

Common situations: Schema migration added language/duration as required after some exports were made; third-party archive generation; field renamed in a fork.

Related errors


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