unslothai/unsloth · error · RuntimeError

sd-cli binary is present but not runnable.

Error message

sd-cli binary is present but not runnable.

What it means

RuntimeError on the one-shot load path: mode resolved to 'oneshot' but engine.version() is None, i.e. the sd-cli binary is present yet cannot execute. Failing at load time (rather than the first generation) gives an early, clear signal.

Source

Thrown at studio/backend/core/inference/sd_cpp_backend.py:1335

                    mode, server_binary, engine = "oneshot", None, fallback
            # The accelerator the managed tree held when THIS binary was chosen, taken where the
            # choice is made rather than sampled again later. The asset download below runs for
            # minutes with no claim on the tree, and an install that lands in that window replaces
            # sd-server in place: same path, still runnable, a different build. "It exists and it
            # runs" is therefore not evidence that it is the build this load resolved its device
            # and offload policy for, so the answer is re-asked under the reader claim.
            server_accelerator = _installed_accelerator_of(server_binary)
            # The same pin for the one-shot CLI, and for the same reason. Sampling it only at
            # state construction, after the download, would record whatever an install left in
            # the tree in that window and the first generation -- which re-reads the tree and
            # compares -- would then agree with the replacement, so the check that exists to
            # notice a swap could never fire for one that landed during the download.
            engine_accelerator = _installed_accelerator_of(getattr(engine, "binary", None))
            if mode == "oneshot":
                # version() is None when a present binary can't run; fail now, not on the first generation.
                assert engine is not None
                if engine.version() is None:
                    raise RuntimeError("sd-cli binary is present but not runnable.")

            # Swap ONCE so the size probe and the download agree: sizes come from paths-info, which
            # -- unlike model_info -- 401s anonymously on a gated repo, so probing the upstream
            # drops the VAE from the progress total the mirror then pulls.
            inner_dim = self._flux2_inner_dim(repo_id, gguf_filename, fam, hf_token)
            specs = self._asset_specs(repo_id, gguf_filename, fam, inner_dim)
            fetch_repo = _fetch_repo_map(specs, hf_token)
            assets = [(fetch_repo[repo], fn, kind) for repo, fn, kind in specs]
            # begin_load could only guess the encoder repos (it may not have had the header yet);
            # now they are known, so publish them before a single byte is fetched. Otherwise
            # delete-cached would happily remove a companion this load is about to write into.
            with self._lock:
                if self._load_token == _load_token and self._loading is not None:
                    self._loading.asset_repos = tuple(
                        dict.fromkeys(r for r, _f, kind in specs if kind != "diffusion_model")
                    )
            # And record them, from the SAME post-probe specs. begin_load records what it can, but
            # it resolves the header offline, so a remote or renamed FLUX.2-klein 9B checkpoint

View on GitHub (pinned to 203007d190)

Solutions

  1. Execute the binary directly to surface the underlying exec failure.
  2. Reinstall the managed binary (delete the tree / allow install) or point SD_CLI_PATH at a working build.
  3. Fix the runtime environment (ldd-reported missing libs, exec permissions).
Defensive patterns

Strategy: retry

Validate before calling

import subprocess

def cli_runs(binary: str) -> bool:
    try:
        return subprocess.run([binary, '--version'], capture_output=True, timeout=20).returncode == 0
    except Exception:
        return False

Try / catch

try:
    backend.begin_load(repo_id=r, gguf_filename=f)
except RuntimeError as e:
    if 'sd-cli binary is present but not runnable' in str(e):
        reinstall_or_repoint_cli()
        backend.begin_load(repo_id=r, gguf_filename=f)
    raise

Prevention

When it happens

Trigger: Load with mode=='oneshot' (older/custom build without the server target, or an injected engine) where the CLI binary is corrupt or its runtime is broken.

Common situations: Partial download of the managed CLI bundle; broken dynamic-library environment; architecture mismatch; file permissions after moving an install.

Related errors


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