unslothai/unsloth · error · ValueError

Invalid transport mode: {mode!r} (transports: {sorted(VALID_

Error message

Invalid transport mode: {mode!r} (transports: {sorted(VALID_TRANSPORTS)}, request modes: {sorted(VALID_TRANSPORT_MODES)})

What it means

Raised by download_registry's cache-preparation layer when `mode` is not one of VALID_TRANSPORTS ({'http','xet'}). Request modes also permit 'auto', but 'auto' must be resolved to a concrete transport before reaching this layer and gets a dedicated error. The message lists both the valid cache transports and the valid request modes to make the mismatch obvious.

Source

Thrown at studio/backend/hub/utils/download_registry.py:776

    ``protected_blob_hashes`` are blobs a concurrent same-repo peer is writing;
    they are excluded from every purge so a shared companion is never deleted
    mid-write.

    Scope: ``root`` selects the cache captured by the caller. It defaults to the
    active ``HF_HUB_CACHE`` root for workers that inherit their cache through
    the environment. Markers are written for the new mode before returning,
    except when an HTTP purge cannot remove every selected partial. Withholding
    the marker keeps the surviving partial untrusted.
    """
    if mode not in VALID_TRANSPORTS:
        if mode == TRANSPORT_AUTO:
            # "auto" is a request preference, not a cache writer: it must be resolved to xet/http
            # before reaching this layer. Naming it turns "invalid transport" into the actual bug.
            raise ValueError(
                f"{TRANSPORT_AUTO!r} must be resolved to a concrete transport before preparing the "
                f"cache; expected one of {sorted(VALID_TRANSPORTS)}"
            )
        raise ValueError(
            f"Invalid transport mode: {mode!r} (transports: {sorted(VALID_TRANSPORTS)}, "
            f"request modes: {sorted(VALID_TRANSPORT_MODES)})"
        )
    root = hf_cache_root(create = True) if root is None else hf_cache_root(create = True, root = root)
    if root is None:
        return 0
    target = target_dir_name(repo_type, repo_id)
    try:
        entries = [e for e in root.iterdir() if e.name.lower() == target]
    except OSError:
        return 0
    if not entries:
        # First download: pre-create the repo dir so the marker lands before the
        # worker writes any bytes. Otherwise a SIGKILL mid-download leaves a
        # partial with no marker that the resume then purges.
        canonical = repo_cache_dir_name(repo_type, repo_id)
        new_entry = root / canonical
        try:

View on GitHub (pinned to 203007d190)

Solutions

  1. Resolve 'auto' to 'http' or 'xet' before calling the cache layer (use the existing resolver used by the download request path).
  2. Pass exactly 'http' or 'xet' (lowercase) — the set is case-sensitive.
  3. Validate config early: reject any transport not in {'http','xet','auto'} at settings-load time with a clear message.

Example fix

# before
prepare_cache_for_download(repo, mode='auto')
# after
mode = resolve_transport('auto')  # -> 'xet' or 'http'
prepare_cache_for_download(repo, mode=mode)
Defensive patterns

Strategy: type-guard

Validate before calling

VALID_TRANSPORTS = {"http", "xet"}
REQUEST_MODES = {"http", "xet", "auto"}

def assert_transport(mode: str) -> str:
    if mode == "auto":
        return resolve_auto_transport()  # existing resolver -> 'http' | 'xet'
    if mode not in VALID_TRANSPORTS:
        raise ValueError(f"transport must be one of {sorted(VALID_TRANSPORTS)}, got {mode!r}")
    return mode

Type guard

from typing import Literal
Transport = Literal['http', 'xet']
RequestMode = Literal['http', 'xet', 'auto']

def is_transport(mode: str) -> bool:
    return mode in ('http', 'xet')

Prevention

When it happens

Trigger: Calling prepare/purge cache APIs with mode='auto' handled elsewhere, but mode='asyncio', 'hf_transfer', a typo like 'Xet' (case-sensitive), or None reaches this function directly instead of via the request-mode resolution path.

Common situations: New code paths (workers, CLI scripts) built directly on the cache layer and skipping transport resolution; config files carrying a stale or misspelled transport value after an upgrade that split request modes from cache transports.

Related errors


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