unslothai/unsloth · error · ValueError

Embedding model must be a Hugging Face repo id (e.g. 'unslot

Error message

Embedding model must be a Hugging Face repo id (e.g. 'unsloth/bge-small-en-v1.5') or a local model path, up to {MAX_EMBEDDING_MODEL_LENGTH} characters.

What it means

Raised by validate_embedding_model when the stored/configured embedding model value fails _coerce_embedding_model: it must be a non-empty string (or string-coercible) that is <= MAX_EMBEDDING_MODEL_LENGTH characters, strips to non-empty, and contains no control characters (any codepoint < 32, including newlines). These constraints match valid HF repo ids or local paths.

Source

Thrown at studio/backend/utils/embedding_model_settings.py:62

    return config.EMBEDDING_MODEL


def _coerce_embedding_model(value: Any) -> str | None:
    if not isinstance(value, str):
        return None
    cleaned = value.strip()
    if not cleaned or len(cleaned) > MAX_EMBEDDING_MODEL_LENGTH:
        return None
    # Newlines/control chars are never valid in a repo id or path.
    if any(ord(ch) < 32 for ch in cleaned):
        return None
    return cleaned


def validate_embedding_model(value: Any) -> str:
    cleaned = _coerce_embedding_model(value)
    if cleaned is None:
        raise ValueError(
            "Embedding model must be a Hugging Face repo id (e.g. "
            "'unsloth/bge-small-en-v1.5') or a local model path, up to "
            f"{MAX_EMBEDDING_MODEL_LENGTH} characters."
        )
    return cleaned


def get_stored_embedding_model() -> str | None:
    """The persisted override, or None when unset/invalid."""
    global _cached
    now = time.monotonic()
    with _lock:
        cached = _cached
        if cached is not None and now - cached[0] < _CACHE_TTL_S:
            return cached[1]
        gen = _generation
    try:
        from storage.studio_db import get_app_setting

View on GitHub (pinned to 203007d190)

Solutions

  1. Set the value to a valid HF repo id like 'unsloth/bge-small-en-v1.5' or an absolute local model path.
  2. Trim whitespace and remove newlines/tabs from the input before saving (the validator strips outer whitespace but rejects embedded control chars).
  3. Verify length is within MAX_EMBEDDING_MODEL_LENGTH.
  4. If it came from a config file, check the file for multiline YAML block scalars accidentally producing embedded newlines.

Example fix

# before
set_embedding_model("unsloth/bge-small-en-v1.5\n")  # trailing newline -> ValueError

# after
set_embedding_model("unsloth/bge-small-en-v1.5".strip())
Defensive patterns

Strategy: validation

Validate before calling

MAX_LEN = 200  # keep in sync with MAX_EMBEDDING_MODEL_LENGTH

def is_valid_embedding_model(value) -> bool:
    if not isinstance(value, str):
        return False
    v = value.strip()
    return (
        0 < len(v) <= MAX_LEN
        and all(ord(ch) >= 32 for ch in v)
    )

# guard: assert is_valid_embedding_model(model_id) before set_embedding_model(model_id)

Type guard

def is_valid_embedding_model(value: object) -> bool:
    if not isinstance(value, str):
        return False
    v = value.strip()
    return bool(v) and len(v) <= 200 and all(ord(c) >= 32 for c in v)

Try / catch

try:
    validate_embedding_model(raw)
except ValueError:
    raise ValueError(f"Embedding model '{raw!r}' is not a valid HF repo id or path") from None

Prevention

When it happens

Trigger: Calling validate_embedding_model (or a settings API that persists the embedding model) with '', whitespace-only strings, values longer than MAX_EMBEDDING_MODEL_LENGTH, non-string junk (dict/list coerced badly), or strings containing \n / \t / other control chars.

Common situations: UI form submitted with an empty field; copy-paste of a model id that includes a trailing newline or embedded tab; a path with a stray carriage return from Windows line endings; an absurdly long pasted blob instead of a repo id.

Related errors


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