jamiepine/voicebox · error · ValueError
Invalid JSON in archive: {e}
Error message
Invalid JSON in archive: {e} What it means
Raised inside the profile import's try block when json.loads() on manifest.json or samples.json throws json.JSONDecodeError. The ZIP itself opens fine, but one of the metadata files inside is not valid JSON (export_import.py:237-238). Wrapped as ValueError(f"Invalid JSON in archive: {e}") with the parser's positional detail preserved.
Source
Thrown at backend/services/export_import.py:238
try:
# Add sample to profile
await add_profile_sample(
profile.id,
tmp_path,
reference_text,
db,
)
finally:
# Clean up temp file
Path(tmp_path).unlink(missing_ok=True)
return profile
except zipfile.BadZipFile:
raise ValueError("Invalid ZIP file")
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON in archive: {e}")
except Exception as e:
if isinstance(e, ValueError):
raise
raise ValueError(f"Error importing profile: {str(e)}")
def export_generation_to_zip(generation_id: str, db: Session) -> bytes:
"""
Export a generation to a ZIP archive.
Args:
generation_id: Generation ID to export
db: Database session
Returns:
ZIP file contents as bytes
Raises:View on GitHub (pinned to 51f49dea19)
Solutions
- Unzip the archive locally and run python -m json.tool manifest.json to find the exact syntax error — the {e} suffix reports line/column.
- Re-export the profile from the source instance rather than hand-editing the archive.
- If migrating across versions, open the ZIP, fix the JSON in place, and rezip preserving the same internal paths (manifest.json, samples.json, samples/*.wav).
- Check for a BOM: strip leading \ufeff from manifest.json before re-zipping.
Example fix
# before: hand-edited manifest with trailing comma
{"version": 1, "profile": {"name": "x",},}
# after: valid JSON
{"version": 1, "profile": {"name": "x"}} Defensive patterns
Strategy: validation
Validate before calling
import json, zipfile, io
def validate_archive_json(file_bytes: bytes) -> None:
with zipfile.ZipFile(io.BytesIO(file_bytes)) as z:
for name in ('manifest.json', 'samples.json'):
if name not in z.namelist():
raise ValueError(f'missing {name}')
try:
json.loads(z.read(name))
except json.JSONDecodeError as e:
raise ValueError(f'{name} is not valid JSON: {e}') Type guard
null
Try / catch
try:
profile = await import_profile_from_bytes(file_bytes, db)
except ValueError as e:
msg = str(e)
if msg.startswith('Invalid JSON in archive'):
raise HTTPException(400, 'Archive metadata is malformed JSON. Re-export the profile.')
raise HTTPException(400, msg) Prevention
- Never hand-edit JSON inside an export archive; re-export instead.
- Run python -m json.tool on extracted manifest/samples files before re-zipping.
- Keep exporter and importer on the same schema version.
When it happens
Trigger: manifest.json or samples.json contains trailing commas, single quotes, comments, or was hand-edited; the file is UTF-16 with a BOM; the file was overwritten by a stray zip entry that is actually audio/text; partial write during a crash left a truncated JSON document.
Common situations: User edited an exported ZIP by hand to rename a profile; an older or newer export format writes a different schema; a sync tool (Dropbox/OneDrive) uploaded a conflicted copy into the archive; export was interrupted and wrote a partial JSON file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ZIP archive missing manifest.json
- ZIP archive missing samples.json
- Invalid manifest.json: missing version
- Invalid manifest.json: missing profile
- Invalid manifest.json: missing generation data
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/1e607b7cafe8186d.
Report an issue: GitHub.