jamiepine/voicebox · error · ValueError
`audio_path` is only available to loopback callers — remote
Error message
`audio_path` is only available to loopback callers — remote callers must use `audio_base64`.
What it means
Raised by voicebox_transcribe when audio_path is supplied and request_is_loopback() is False. The audio_path mode reads arbitrary local files, so it is deliberately restricted to loopback (same-host) callers to prevent a Voicebox bound on 0.0.0.0 from becoming an unauthenticated arbitrary-local-file read primitive.
Source
Thrown at backend/mcp_server/tools.py:139
),
)
async def voicebox_transcribe(
audio_base64: str | None = None,
audio_path: str | None = None,
language: str | None = None,
model: str | None = None,
) -> dict[str, Any]:
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:View on GitHub (pinned to 51f49dea19)
Solutions
- Switch the remote caller to audio_base64 (works from anywhere).
- Run the file-path caller on the same host as Voicebox and connect via 127.0.0.1/localhost.
- Do NOT widen this guard — it is intentional; instead encode the file as base64 remotely.
Example fix
// before (remote caller)
voicebox_transcribe(audio_path="/var/data/clip.wav")
// after
voicebox_transcribe(audio_base64=base64.b64encode(open("/var/data/clip.wav","rb").read()).decode()) Defensive patterns
Strategy: validation
Validate before calling
from backend.mcp_server.context import request_is_loopback
if audio_path and not request_is_loopback():
# encode and send as base64 instead
import base64
audio_base64 = base64.b64encode(open(audio_path, "rb").read()).decode()
audio_path = None
await voicebox_transcribe(audio_base64=audio_base64, audio_path=audio_path) Type guard
def can_use_audio_path() -> bool:
from backend.mcp_server.context import request_is_loopback
return request_is_loopback() Try / catch
try:
await voicebox_transcribe(audio_path=audio_path)
except ValueError as exc:
if "loopback callers" in str(exc):
import base64
await voicebox_transcribe(
audio_base64=base64.b64encode(open(audio_path, "rb").read()).decode()
)
else:
raise Prevention
- Default remote clients to audio_base64; never send audio_path from off-host.
- Bind Voicebox to 127.0.0.1 if file-path mode is required and only local clients exist.
- Do not attempt to bypass request_is_loopback — it is a deliberate security boundary.
When it happens
Trigger: A remote MCP client (request arriving over a non-loopback interface) calling voicebox_transcribe(audio_path=...); running Voicebox on 0.0.0.0 or behind a reverse proxy that does not preserve the loopback origin.
Common situations: Exposing Voicebox to LAN/public while still trying to use file-path mode; proxy/TLS terminator rewriting the source address so the request no longer looks loopback; mixing local and remote clients against one instance.
Related errors
- `audio_path` must be absolute.
- File not found: {audio_path}
- 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/33d1a95575f2e711.
Report an issue: GitHub.