jamiepine/voicebox · error · ValueError
Invalid sample filename: {filename} (must be .wav)
Error message
Invalid sample filename: {filename} (must be .wav) What it means
Each key in samples.json must end with '.wav' (case-sensitive endswith check). The importer extracts each referenced file to a temp .wav and passes it to add_profile_sample; a non-wav key is rejected before extraction.
Source
Thrown at backend/services/export_import.py:207
# Extract to temporary file
import tempfile
with tempfile.NamedTemporaryFile(suffix=Path(avatar_file).suffix, delete=False) as tmp:
tmp.write(zip_file.read(avatar_file))
tmp_path = tmp.name
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,View on GitHub (pinned to 51f49dea19)
Solutions
- Convert source audio to .wav and re-export.
- If only the extension differs, rename keys (and the matching zip entries) to lowercase .wav.
- Ensure the exporter only ever emits .wav.
Example fix
// before
{"clip.mp3": "hello"}
// after
{"clip.wav": "hello"} Defensive patterns
Strategy: validation
Validate before calling
import io, json, zipfile
def all_keys_wav(file_bytes) -> bool:
with zipfile.ZipFile(io.BytesIO(file_bytes)) as z:
return all(k.endswith(".wav") for k in json.loads(z.read("samples.json"))) Type guard
def is_wav_filename(name) -> bool:
return isinstance(name, str) and name.lower().endswith(".wav") Try / catch
try:
await import_profile_from_zip(file_bytes, db)
except ValueError as e:
if "must be .wav" in str(e):
# convert audio to wav, rename keys + zip entries, retry
...
raise Prevention
- Normalize all imported audio to .wav before zipping.
- Watch for uppercase .WAV on macOS/Windows exports — normalize to lowercase.
When it happens
Trigger: samples.json contains a .mp3/.flac/.txt key or an extensionless key; case mismatch such as '.WAV' (uppercase) failing the case-sensitive endswith('.wav') check.
Common situations: Mixing audio formats in a hand-built archive; uppercase extension coming from a case-insensitive filesystem export (macOS/Windows).
Related errors
- Invalid samples.json: must be a dictionary
- Sample file not found in ZIP: {zip_path}
- ZIP archive missing manifest.json
- ZIP archive missing samples.json
- Invalid manifest.json: missing version
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/724f3b6896f3608f.
Report an issue: GitHub.