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 checkpointView on GitHub (pinned to 203007d190)
Solutions
- Execute the binary directly to surface the underlying exec failure.
- Reinstall the managed binary (delete the tree / allow install) or point SD_CLI_PATH at a working build.
- 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
- Verify the sd-cli binary executes on the target host before relying on one-shot mode.
- Reinstall the managed bundle after OS upgrades that change dynamic libraries.
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
- sd-server binary is present but not runnable.
- The executable at {binary} is not stable-diffusion.cpp: its
- sd-cli (stable-diffusion.cpp) binary is unavailable.
- stable-diffusion.cpp could not be installed or started for M
- The stable-diffusion.cpp binary at {binary} does not adverti
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/00705f28d569920d.
Report an issue: GitHub.