jamiepine/voicebox · error · ValueError
Unknown LLM engine: {engine}. Supported: {list(LLM_ENGINES.k
Error message
Unknown LLM engine: {engine}. Supported: {list(LLM_ENGINES.keys())} What it means
Raised as a ValueError by get_llm_backend_for_engine() when the engine string is not 'qwen_llm' (the only key in LLM_ENGINES). The message interpolates list(LLM_ENGINES.keys()). Like the TTS variant, it is a raw ValueError that will surface as a 500 unless a handler converts it.
Source
Thrown at backend/backends/__init__.py:784
if engine in _llm_backends:
return _llm_backends[engine]
with _llm_backends_lock:
if engine in _llm_backends:
return _llm_backends[engine]
if engine == "qwen_llm":
backend_type = get_backend_type()
if backend_type == "mlx":
from .qwen_llm_backend import MLXQwenLLMBackend
backend = MLXQwenLLMBackend()
else:
from .qwen_llm_backend import PyTorchQwenLLMBackend
backend = PyTorchQwenLLMBackend()
else:
raise ValueError(f"Unknown LLM engine: {engine}. Supported: {list(LLM_ENGINES.keys())}")
_llm_backends[engine] = backend
return backend
def reset_backends():
"""Reset backend instances (useful for testing)."""
global _tts_backend, _tts_backends, _stt_backend, _llm_backends
_tts_backend = None
_tts_backends.clear()
_stt_backend = None
_llm_backends.clear()
View on GitHub (pinned to 51f49dea19)
Solutions
- Validate engine against LLM_ENGINES.keys() before calling get_llm_backend_for_engine().
- When adding an LLM engine, add both the LLM_ENGINES entry and the if/elif branch together.
- Catch ValueError at the API boundary and return a 400 with the supported list.
- Default callers should use get_llm_backend() (hardcoded 'qwen_llm') to avoid ever hitting this.
Example fix
# before
raise ValueError(f"Unknown LLM engine: {engine}. Supported: {list(LLM_ENGINES.keys())}")
# after
from fastapi import HTTPException
raise HTTPException(status_code=400, detail=f"Unknown LLM engine: {engine}. Supported: {list(LLM_ENGINES.keys())}") Defensive patterns
Strategy: validation
Validate before calling
from backend.backends import LLM_ENGINES
def assert_valid_llm_engine(engine: str) -> None:
if engine not in LLM_ENGINES:
raise ValueError(f'Unsupported LLM engine: {engine}. Supported: {list(LLM_ENGINES)}')
# Prefer the default helper, which always passes qwen_llm:
backend = get_llm_backend() Type guard
def is_known_llm_engine(engine: str) -> bool:
return engine in LLM_ENGINES Try / catch
from fastapi import HTTPException
try:
backend = get_llm_backend_for_engine(engine)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e)) from e Prevention
- Default callers should use get_llm_backend() (hardcoded 'qwen_llm').
- Add the LLM_ENGINES entry and the matching if/elif branch together for new engines.
- Catch ValueError at the API boundary and return a 400 with the supported list.
- Validate persisted settings referencing an LLM engine after renames.
When it happens
Trigger: A caller requests an LLM engine other than 'qwen_llm' — e.g. a future 'ollama' or 'llama_cpp' engine wired on the client but not yet implemented, or a typo. The default helper get_llm_backend() always passes 'qwen_llm' and never triggers this.
Common situations: Frontend/backend version skew shipping a new LLM engine selector before backend support. Persisted settings referencing a renamed engine. Exploratory code passing an arbitrary string.
Related errors
- Unknown TTS engine: {engine}. Supported: {list(TTS_ENGINES.k
- Model ${model_size} is not downloaded yet. Use /generate to
- Model {model_size} is not downloaded yet. Use /generate to t
- {display} model is not downloaded yet. Use /generate to trig
- {e}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/2ee31d2cfc4e6a53.
Report an issue: GitHub.