unslothai/unsloth · error · RuntimeError

sd-cli timed out after {timeout}s

Error message

sd-cli timed out after {timeout}s

What it means

The sd-cli subprocess watchdog kills the process tree and raises this when the monotonic deadline (start + timeout) passes while the process is still running. The loop polls every 100ms and distinguishes timeout from cancellation (cancel raises SdCppCancelled instead). A None timeout disables the check entirely.

Source

Thrown at studio/backend/core/inference/sd_cpp_engine.py:795

                for rec in iter_sd_cpp_records(proc.stdout):
                    line_q.put(rec)
            finally:
                line_q.put(None)

        reader = threading.Thread(target = _drain, daemon = True)
        reader.start()

        deadline = None if timeout is None else time.monotonic() + float(timeout)
        stdout_done = False
        try:
            while True:
                # Cancellation: kill the process tree and signal cancelled, not failure.
                if cancel_event is not None and cancel_event.is_set() and proc.poll() is None:
                    _terminate(proc)
                    raise SdCppCancelled("sd-cli generation was cancelled.")
                if deadline is not None and time.monotonic() >= deadline and proc.poll() is None:
                    _terminate(proc)
                    raise RuntimeError(f"sd-cli timed out after {timeout}s")
                try:
                    line = line_q.get(timeout = 0.1)
                except queue.Empty:
                    if proc.poll() is not None and stdout_done:
                        break
                    continue
                if line is None:
                    stdout_done = True
                    if proc.poll() is not None:
                        break
                    continue
                tail.append(line)
                if len(tail) > 40:
                    tail.pop(0)
                if on_log is not None:
                    on_log(line)
            ret = proc.wait(timeout = 5.0)
        finally:

View on GitHub (pinned to 203007d190)

Solutions

  1. Pass a larger (or None) timeout to the generate call.
  2. Reduce steps, resolution, or batch size so the run fits the budget.
  3. Free the machine (close competing GPU/CPU jobs) or move to the server path, which streams progress and handles long runs better.

Example fix

# before
engine.generate(files, params, output_path=out, timeout=60)
# after
engine.generate(files, params, output_path=out, timeout=1800)
Defensive patterns

Strategy: retry

Validate before calling

estimated = steps * (width * height) / 500_000  # rough seconds heuristic
timeout = max(timeout, estimated * 4)

Try / catch

try:
    engine.generate(files, params, output_path=out, timeout=t)
except RuntimeError as e:
    if "timed out" in str(e) and t is not None:
        engine.generate(files, params, output_path=out, timeout=t * 3)
    raise

Prevention

When it happens

Trigger: Calling the CLI generate with a finite timeout smaller than the actual generation time — big resolutions, many steps, LoRA materialization, or CPU-only execution easily exceed tight defaults.

Common situations: Default timeout on slow hardware; steps/resolution raised without raising timeout; heavy machine load (another model training) starving the CLI of CPU/GPU.

Understand the failure class

Related errors


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