unslothai/unsloth · error · RuntimeError
sd-server returned {len(blobs)} of {count} requested images
Error message
sd-server returned {len(blobs)} of {count} requested images in the batch. What it means
The sd-server img_gen call returned fewer image blobs than the requested batch count for a chunk. The backend enforces all-or-nothing per chunk: a partial batch is failed loudly rather than silently returning fewer images, because seeds and image positions in the batch would desync. It is skipped only when the cancel event is set (cancellation path takes over).
Source
Thrown at studio/backend/core/inference/sd_cpp_backend.py:2300
)
except RuntimeError as exc:
# A ggml unsupported-op abort killed the server: this graph cannot run on the GPU backend at all, so restart the model on the CPU backend once and retry this chunk. Any other death propagates.
server = self._restart_server_on_cpu_backend(state, str(exc), cancel)
if server is None:
raise
state = replace(state, server = server)
with self._lock:
if self._state is not None and self._state.server is not None:
self._state = state
blobs = server.img_gen(
payload,
on_step = self._on_log,
cancel_event = cancel,
total_timeout = max(deadline - time.monotonic(), 1.0),
)
# All-or-nothing per chunk: fail rather than silently drop images from the batch.
if not cancel.is_set() and len(blobs) != count:
raise RuntimeError(
f"sd-server returned {len(blobs)} of {count} requested images in the batch."
)
images.extend(Image.open(io.BytesIO(b)).convert("RGB") for b in blobs)
# sd.cpp advances the seed per image within a job, so report chunk_seed+i.
seeds.extend((chunk_seed + i) & ((1 << 63) - 1) for i in range(len(blobs)))
finally:
if lora_stage is not None:
shutil.rmtree(lora_stage, ignore_errors = True)
return images, seeds
def _restart_server_on_cpu_backend(
self, state: _SdState, error_text: str, cancel: threading.Event
) -> Optional[SdCppServer]:
"""Relaunch this checkpoint's sd-server with ``--backend cpu``; None if that does not apply.
ggml's Metal backend checks every node against ``ggml_metal_device_supports_op`` and calls
``GGML_ABORT`` when one is not implemented for that device, because a single-backend graph
has nowhere else to put the node -- there is no per-op CPU fallback. The whole sd-serverView on GitHub (pinned to 203007d190)
Solutions
- Retry the generation; transient server drops usually resolve on a fresh job.
- Reduce batch_size (or chunk size) to lower per-job memory pressure.
- If it reproduces deterministically, capture the sd-server log tail and check for OOM/crash lines; restart or reload the server.
- Verify the installed sd-server version matches what the backend expects (reinstall via the studio updater).
Defensive patterns
Strategy: retry
Validate before calling
assert count >= 1 and batch_size >= 1, "batch count must be positive"
Try / catch
try:
images, seeds = backend.generate(...)
except RuntimeError as e:
if "requested images in the batch" in str(e):
retry_with_smaller_batch()
raise Prevention
- Keep batch_size modest relative to available VRAM.
- Watch server memory trends across batches; restart the server when fragmentation builds up.
- Treat partial-batch failures as retryable, and surface which chunk failed.
When it happens
Trigger: Requesting batch_size > 1 (or a chunked batch) and the server returns len(blobs) != count while not cancelled — e.g. server-side crash mid-batch, truncated response, or a server bug dropping images.
Common situations: Large batches on memory-constrained GPUs where the server dies partway; mismatches between client and server batch semantics after a version change.
Related errors
- The stable-diffusion.cpp binary was replaced by an install f
- sd-cli (stable-diffusion.cpp) binary not found. Build it or
- sd-cli timed out after {timeout}s
- sd-cli exited {ret}. Last output: {"\n".join(tail[-12:])}
- sd-cli reported success but no image at {out}. Last output:
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/a6b3bc1bc14c0147.
Report an issue: GitHub.