odysseus-dev/odysseus · error · HTTPException
STT service not available or set to browser mode
Error message
STT service not available or set to browser mode
What it means
503 from POST /api/stt/transcribe: stt_service.available is false, meaning the server has no server-side speech-to-text backend — either no provider is configured (no local Whisper, no API endpoint) or STT is deliberately set to browser mode, where transcription happens in the client and this endpoint is not the right path.
Source
Thrown at routes/stt_routes.py:30
def setup_stt_routes(stt_service):
"""Setup STT routes with the provided STT service"""
router = APIRouter(prefix="/api/stt", tags=["stt"])
@router.get("/stats")
async def get_stt_stats():
"""Get STT service statistics"""
try:
return stt_service.get_stats()
except Exception as e:
logger.error(f"Failed to get STT stats: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/transcribe")
async def transcribe_audio(file: UploadFile = File(...)):
"""Transcribe uploaded audio file to text"""
try:
if not stt_service.available:
raise HTTPException(
status_code=503,
detail={"message": "STT service not available or set to browser mode"}
)
audio_bytes = await read_upload_limited(file, STT_MAX_AUDIO_BYTES, "Audio file")
if not audio_bytes:
raise HTTPException(status_code=400, detail={"message": "Empty audio file"})
text = stt_service.transcribe(audio_bytes)
if text is None:
raise HTTPException(
status_code=500,
detail={"message": "Transcription failed"}
)
return {"text": text}
except HTTPException:View on GitHub (pinned to f9235ebbf1)
Solutions
- If browser mode is intended, use the browser STT path client-side and stop calling /transcribe.
- To use server-side STT, configure a provider (local Whisper model or API endpoint) and restart so stt_service.available becomes true.
- Check GET /api/stt/stats to see availability and provider state before sending audio.
- Verify the STT dependency installed and the model downloaded (first-run downloads need network).
Example fix
# before
r = client.post("/api/stt/transcribe", files={"file": audio}) # 503
r.raise_for_status()
# after
stats = client.get("/api/stt/stats").json()
if not stats.get("available"):
transcript = browser_webspeech_transcribe(audio) # or configure server STT
else:
r = client.post("/api/stt/transcribe", files={"file": audio})
r.raise_for_status()
transcript = r.json()["text"] Defensive patterns
Strategy: type-guard
Validate before calling
stats = client.get(f"{base}/api/stt/stats").json()
if not stats.get("available"):
raise ServiceUnavailable("server STT off/browser mode — configure a provider or use browser STT") Type guard
def stt_ready(stt_service) -> bool:
"""True when the server can transcribe uploads right now."""
return bool(getattr(stt_service, "available", False)) Try / catch
r = client.post(f"{base}/api/stt/transcribe", files={"file": f})
if r.status_code == 503:
transcript = browser_fallback_stt(audio_source) # or prompt admin to configure server STT
else:
r.raise_for_status()
transcript = r.json()["text"] Prevention
- Check /api/stt/stats before uploading audio.
- Decide the STT mode once at app init: browser mode never calls /transcribe.
- After install or upgrade, verify the Whisper model/dependency loads (available=True) before shipping to users.
When it happens
Trigger: POST /transcribe on a server whose STT config is 'browser'; a deployment where the Whisper model/dependency was never installed; the STT provider failed to initialize at startup (model load failure) leaving available=False.
Common situations: Default install with browser-based WebSpeech STT expected but the client calls the REST endpoint anyway; missing whisper/faster-whisper dependency or model download blocked; STT provider credentials absent.
Related errors
- HTTP ${res.status}${body ? ': ' + body.slice(0, 160) : ''}
- Transcription failed
- Admin only
- Invalid SSH remote host
- Error: email MCP requires an authenticated owner or ODYSSEUS
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/8178b766c40b5c44.
Report an issue: GitHub.