unslothai/unsloth · error · ValueError

Local checkpoint '{repo_id}' is not a .safetensors file; a '

Error message

Local checkpoint '{repo_id}' is not a .safetensors file; a 'single_file' load needs a .safetensors checkpoint.

What it means

Mirror of [451] for single_file loads of a local FILE: the file's suffix must be .safetensors because the loader passes local files straight through and the single_file path only deserializes safetensors.

Source

Thrown at studio/backend/core/inference/video.py:1239

            path_shaped = (
                repo_id.startswith(("/", "\\", "~", ".")) or "\\" in repo_id or root.is_absolute()
            )
            if root.is_dir():
                from .diffusion_families import resolve_local_gguf_child
                try:
                    resolve_local_gguf_child(root, gguf_filename or "")
                except Exception as exc:  # noqa: BLE001 -- surface as client input error
                    raise ValueError(str(exc)) from exc
            elif root.is_file():
                # The loader hands a local FILE straight through (ignoring gguf_filename), so the file's own suffix must match the kind.
                suffix = root.suffix.lower()
                if kind == "gguf" and suffix != ".gguf":
                    raise ValueError(
                        f"Local checkpoint '{repo_id}' is not a .gguf file; a 'gguf' load "
                        f"needs a .gguf checkpoint."
                    )
                if kind == "single_file" and suffix != ".safetensors":
                    raise ValueError(
                        f"Local checkpoint '{repo_id}' is not a .safetensors file; a "
                        f"'single_file' load needs a .safetensors checkpoint."
                    )
            elif path_shaped:
                raise ValueError(f"Local model path '{repo_id}' does not exist.")
        # A local pipeline pick must be a diffusers directory (model_index.json), else it would only fail after eviction.
        if kind == "pipeline":
            root = Path(repo_id).expanduser()
            # Gate on .exists() (not .is_dir()) so a local FILE picked as a pipeline is rejected too.
            indexes = (
                ("model_index.json", "modular_model_index.json")
                if fam.modular_workflow
                else ("model_index.json",)
            )
            if root.exists() and not (
                root.is_dir() and any((root / name).is_file() for name in indexes)
            ):
                raise ValueError(

View on GitHub (pinned to 203007d190)

Solutions

  1. Convert the file to .safetensors and retry.
  2. If it is a .gguf file, switch model_kind to 'gguf'.
  3. If it is a whole pipeline directory you meant to load, pass the directory with model_kind='pipeline' instead of a file.

Example fix

# before
load(repo_id='/models/wan25.ckpt', model_kind='single_file')

# after (convert once)
load(repo_id='/models/wan25.safetensors', model_kind='single_file')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
root = Path(repo_id).expanduser()
if root.is_file() and model_kind == 'single_file' and root.suffix.lower() != '.safetensors':
    raise ValueError('single_file local load needs a .safetensors file')  # client-side

Type guard

def local_single_file_ok(repo_id: str, kind: str) -> bool:
    root = Path(repo_id).expanduser()
    return not root.is_file() or not (kind == 'single_file' and root.suffix.lower() != '.safetensors')

Prevention

When it happens

Trigger: load(repo_id='/models/denoiser.ckpt', model_kind='single_file') — repo_id is an existing file whose suffix is not .safetensors (e.g. .ckpt, .pt, .gguf, .bin).

Common situations: Legacy .ckpt files; passing a GGUF file path while kind stayed 'single_file'; symlinks or extensionless temp downloads.

Related errors


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