unslothai/unsloth · error · SttModelIdError

STT model must be one of Studio's defaults or a Hugging Face

Error message

STT model must be one of Studio's defaults or a Hugging Face repository in 'owner/model' form.

What it means

SttModelIdError (a ValueError) raised by resolve_model_id() when the model string is neither empty (which resolves to DEFAULT_STT_MODEL), a key of STT_MODELS (curated defaults), nor a fullmatch of the 'owner/model' Hugging Face repository regex _HF_REPO_ID.

Source

Thrown at studio/backend/core/inference/stt_sidecar.py:309

def is_available() -> bool:
    """True when the complete local Whisper backend can be imported."""
    try:
        ensure_stt_available()
    except SttUnavailableError:
        return False
    return True


def resolve_model_id(model: Optional[str]) -> str:
    """Resolve a curated id or validate a custom Hugging Face repository."""
    if not model:
        return DEFAULT_STT_MODEL
    normalized = model.strip()
    if normalized in STT_MODELS:
        return normalized
    if _HF_REPO_ID.fullmatch(normalized):
        return normalized
    raise SttModelIdError(
        "STT model must be one of Studio's defaults or a Hugging Face "
        "repository in 'owner/model' form."
    )


def resolve_model_repo(model_id: str) -> str:
    """Return the Hub repository for a curated or custom model id."""
    resolved = resolve_model_id(model_id)
    return STT_MODELS.get(resolved, resolved)


def _is_whisper_config(config: object) -> bool:
    """True when Hub/local config metadata identifies a Whisper ASR model."""
    if not isinstance(config, dict):
        return False
    model_type = config.get("model_type")
    if isinstance(model_type, str) and model_type.strip().lower() == "whisper":
        return True

View on GitHub (pinned to 203007d190)

Solutions

  1. Use one of the curated ids from STT_MODELS or a full 'owner/model' repository id.
  2. Validate with resolve_model_id() (or the _HF_REPO_ID pattern) in the UI/API before submitting.
  3. Pass empty/None to get the default model instead of an ad-hoc string.

Example fix

```python
# before
model_id = request.args["model"]  # e.g. "whisper-large-v3"
repo = resolve_model_repo(model_id)  # raises SttModelIdError

# after
from studio.backend.core.inference.stt_sidecar import resolve_model_id, SttModelIdError

try:
    model_id = resolve_model_id(request.args.get("model"))
except SttModelIdError:
    return "Model must be a default id or 'owner/model'", 400
```
Defensive patterns

Strategy: validation

Validate before calling

```python
from studio.backend.core.inference.stt_sidecar import STT_MODELS, _HF_REPO_ID

def valid_stt_model(model: str | None) -> bool:
    if not model:
        return True  # default
    n = model.strip()
    return n in STT_MODELS or bool(_HF_REPO_ID.fullmatch(n))
```

Type guard

```python
def is_valid_stt_model_id(model: object) -> TypeGuard[str | None]:
    if model is None:
        return True
    if not isinstance(model, str):
        return False
    n = model.strip()
    return not n or n in STT_MODELS or bool(_HF_REPO_ID.fullmatch(n))
```

Try / catch

```python
try:
    model_id = resolve_model_id(raw_input)
except SttModelIdError:
    return "Use a Studio default or 'owner/model' form", 400
```

Prevention

When it happens

Trigger: Passing a model like "whisper-large-v3" (no owner), "openai/whisper-large-v3/extra", "../local/path", or stray whitespace-surrounded invalid ids (input is stripped first, so only invalid shapes after strip fail).

Common situations: Users typing a bare model name instead of 'owner/model'; copy-paste with trailing slashes or fragments; frontend sending an unvalidated free-text field; API consumers passing a local path.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/a8a6507947f1da3e. Report an issue: GitHub.