jamiepine/voicebox · error · ValueError
File not found: {audio_path}
Error message
File not found: {audio_path} What it means
Raised by voicebox_transcribe when audio_path passes the loopback and absolute checks but Path(audio_path).is_file() is False — i.e. nothing readable exists at that path when the server checks.
Source
Thrown at backend/mcp_server/tools.py:147
if bool(audio_base64) == bool(audio_path):
raise ValueError(
"Pass exactly one of `audio_base64` or `audio_path`."
)
# Absolute-path mode: validate and transcribe in place. Restricted
# to loopback callers so a Voicebox bound on 0.0.0.0 doesn't double
# as an unauthenticated arbitrary-local-file read primitive.
if audio_path is not None:
if not request_is_loopback():
raise ValueError(
"`audio_path` is only available to loopback callers — "
"remote callers must use `audio_base64`."
)
path = Path(audio_path)
if not path.is_absolute():
raise ValueError("`audio_path` must be absolute.")
if not path.is_file():
raise ValueError(f"File not found: {audio_path}")
if path.stat().st_size > MAX_TRANSCRIBE_BYTES:
raise ValueError(
f"File exceeds {MAX_TRANSCRIBE_BYTES // (1024 * 1024)} MB limit."
)
return await _transcribe_file(path, language, model)
# Base64 mode: decode into a temp file, transcribe, clean up.
try:
raw = b64.b64decode(audio_base64, validate=True)
except Exception as exc:
raise ValueError(f"Invalid audio_base64: {exc}") from exc
if len(raw) > MAX_TRANSCRIBE_BYTES:
raise ValueError(
f"Audio exceeds {MAX_TRANSCRIBE_BYTES // (1024 * 1024)} MB limit."
)
with tempfile.NamedTemporaryFile(
suffix=".wav", delete=False
) as tmp:View on GitHub (pinned to 51f49dea19)
Solutions
- Confirm the file exists from the Voicebox server's perspective (not the client's): ls -l on the host/container.
- Mount/share the directory into the Voicebox process if it runs in a container.
- Check the Voicebox process has read permission on the file.
- Re-verify the path is absolute and points to a regular file, not a directory or symlink.
Example fix
// before voicebox_transcribe(audio_path="/data/clip.wav") # missing on server // after # ensure /data is mounted into the Voicebox container, then voicebox_transcribe(audio_path="/data/clip.wav")
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
p = Path(audio_path)
if not p.is_absolute() or not p.is_file():
raise FileNotFoundError(f"audio not found or not absolute: {audio_path}")
await voicebox_transcribe(audio_path=str(p)) Type guard
def audio_path_is_readable(value: str) -> bool:
from pathlib import Path
p = Path(value)
return p.is_absolute() and p.is_file() and p.stat().st_size > 0 Try / catch
try:
await voicebox_transcribe(audio_path=audio_path)
except ValueError as exc:
if "File not found" in str(exc):
# verify on the server host, remount storage if needed, then retry
raise FileNotFoundError(f"server cannot read {audio_path}; check mounts/permissions")
raise Prevention
- If Voicebox runs in a container, mount the audio directory into it.
- Confirm the file is readable by the Voicebox process uid.
- Validate existence+readability on the server host before each call.
When it happens
Trigger: Pointing audio_path at a path that does not exist, is a directory, lives outside an unmounted volume, or is unreadable due to permissions (the is_file check can fail on broken symlinks).
Common situations: Client and server disagree on the filesystem (container vs host paths); file was deleted between submission and check; wrong working directory used to build an 'absolute' path; permission mode hides the file from the Voicebox process.
Related errors
- `audio_path` is only available to loopback callers — remote
- `audio_path` must be absolute.
- File exceeds {MAX_TRANSCRIBE_BYTES // (1024 * 1024)} MB limi
- Pass exactly one of `audio_base64` or `audio_path`.
- Invalid audio_base64: {exc}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/9342b7ee036ffb9e.
Report an issue: GitHub.