jamiepine/voicebox · error · ValueError

Audio file not found

Error message

Audio file not found: {audio_path}

What it means

resolve_storage_path() returned a real Path but that file does not exist() on disk. Distinct from error 231 (un-resolvable path): here the path resolves but the bytes are gone. The message uses the resolved Path so the operator knows where the file was expected.

Solutions

  1. Restore the missing .wav from backup to the resolved path.
  2. If unrecoverable, delete the orphaned DBProfileSample row and re-record.
  3. Check filesystem permissions on the profiles directory.

Example fix

# before
if not audio_path.exists():
    raise ValueError(f"Audio file not found: {audio_path}")

# after — skip missing with a warning rather than failing the whole export
if not audio_path.exists():
    logger.warning("missing sample %s for profile %s; skipping", audio_path, profile_id)
    continue
Defensive patterns

Strategy: validation

Validate before calling

from backend import config
from backend.database import ProfileSample as DBProfileSample

def all_sample_files_present(profile_id, db) -> bool:
    for s in db.query(DBProfileSample).filter_by(profile_id=profile_id):
        p = config.resolve_storage_path(s.audio_path)
        if p is None or not p.exists():
            return False
    return True

Try / catch

try:
    data = export_profile_to_zip(pid, db)
except ValueError as e:
    if "Audio file not found" in str(e):
        # prompt user to repair/re-record the missing sample
        ...
    raise

Prevention

When it happens

Trigger: Sample file deleted/moved from disk while the DB row remains; backup restored the DB but not the audio; filesystem permissions making exists() return False.

Common situations: Manual cleanup of the profiles directory; antivirus quarantining .wav files; partial disk failure; sync tool that didn't pull audio files.

Related errors


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

Appendix: source

Thrown at backend/services/export_import.py:108

            },
            "has_avatar": has_avatar,
        }
        zip_file.writestr("manifest.json", json.dumps(manifest, indent=2))

        # Create samples.json mapping
        samples_data = {}
        profile_dir = config.get_profiles_dir() / profile_id

        for sample in samples:
            # Get filename from audio_path (should be {sample_id}.wav)
            audio_path = config.resolve_storage_path(sample.audio_path)
            if audio_path is None:
                raise ValueError(f"Audio file not found: {sample.audio_path}")
            filename = audio_path.name

            # Read audio file
            if not audio_path.exists():
                raise ValueError(f"Audio file not found: {audio_path}")

            # Add to samples directory in ZIP
            zip_path = f"samples/{filename}"
            zip_file.write(audio_path, zip_path)

            # Map filename to reference text
            samples_data[filename] = sample.reference_text

        zip_file.writestr("samples.json", json.dumps(samples_data, indent=2))
    
    zip_buffer.seek(0)
    return zip_buffer.read()


async def import_profile_from_zip(file_bytes: bytes, db: Session) -> VoiceProfileResponse:
    """
    Import a voice profile from a ZIP archive.
    

View on GitHub (pinned to 51f49dea19)