jamiepine/voicebox · error · ValueError
Sample file not found in ZIP: {zip_path}
Error message
Sample file not found in ZIP: {zip_path} What it means
For each filename key in samples.json the importer expects a matching samples/{filename} entry in the ZIP namelist. If it's absent the importer raises rather than silently skipping referenced audio. The path is built with a forward slash: f"samples/{filename}".
Source
Thrown at backend/services/export_import.py:213
try:
from .profiles import upload_avatar
await upload_avatar(profile.id, tmp_path, db)
finally:
Path(tmp_path).unlink(missing_ok=True)
except Exception as e:
# Avatar import is optional - continue even if it fails
pass
for filename, reference_text in samples_data.items():
# Validate filename
if not filename.endswith('.wav'):
raise ValueError(f"Invalid sample filename: {filename} (must be .wav)")
# Extract audio file to temp location
zip_path = f"samples/{filename}"
if zip_path not in namelist:
raise ValueError(f"Sample file not found in ZIP: {zip_path}")
# Extract to temporary file
import tempfile
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
tmp.write(zip_file.read(zip_path))
tmp_path = tmp.name
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)View on GitHub (pinned to 51f49dea19)
Solutions
- Re-export so samples.json and the audio entries stay consistent.
- Check case and path separators — namelist uses forward slashes; rebuild on the same OS if needed.
- Remove orphan keys from samples.json or add the missing audio entries.
Example fix
# before — samples.json says 'abc.wav' but the zip has 'samples/ABC.wav' # after — keep names consistent: lowercase keys, matching 'samples/<name>' entries, forward slashes
Defensive patterns
Strategy: validation
Validate before calling
import io, json, zipfile
def samples_match_entries(file_bytes) -> bool:
with zipfile.ZipFile(io.BytesIO(file_bytes)) as z:
names = set(z.namelist())
return all(f"samples/{k}" in names for k in json.loads(z.read("samples.json"))) Try / catch
try:
await import_profile_from_zip(file_bytes, db)
except ValueError as e:
if "Sample file not found in ZIP" in str(e):
# reconcile samples.json keys with archive entries (case/separators)
...
raise Prevention
- Only import archives from the official exporter.
- On case-sensitive filesystems (Linux) keep filenames lowercase and stable.
- Validate that every samples.json key has a matching samples/<key> entry before import.
When it happens
Trigger: samples.json references 'abc.wav' but the archive contains 'samples/ABC.wav' (case mismatch), the audio entry was never added, or backslash separators from a Windows-built zip don't match the forward-slash lookup.
Common situations: Hand-edited samples.json not matching zip contents; case-sensitivity crossing OSes (Linux import of a Windows-built zip); partial zip assembly.
Related errors
- ZIP archive missing manifest.json
- ZIP archive missing samples.json
- Invalid samples.json: must be a dictionary
- Invalid sample filename: {filename} (must be .wav)
- {e}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/f6f324920830306d.
Report an issue: GitHub.