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
- Re-export with the current exporter (it always writes version: "1.0").
- If constructing manually, set manifest.version = "1.0".
- 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
- Only import archives produced by a known exporter version.
- Pre-validate manifest keys (version, profile) client-side.
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
- Invalid manifest.json: missing profile
- ZIP archive missing manifest.json
- ZIP archive missing samples.json
- Invalid samples.json: must be a dictionary
- Invalid manifest.json: missing generation data
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/3bf85a1d6ee5f9a0.
Report an issue: GitHub.