unslothai/unsloth · error · ValueError

img2img / inpaint / reference / upscale are not yet supporte

Error message

img2img / inpaint / reference / upscale are not yet supported on the native sd.cpp engine; run on a GPU (diffusers) for image-conditioned workflows.

What it means

ValueError at the top of native generate: the sd.cpp engine implements text-to-image only. init_image, mask_image, reference_images, or upscale>1 request image-conditioned workflows (img2img/inpaint/reference/upscale) that the native engine cannot run, so it fails fast with a pointer to the diffusers engine on GPU.

Source

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

        reference_images: Optional[list[str]] = None,  # GPU/diffusers-only (FLUX.2)
        # LoRA (id, weight) pairs; resolved up front then applied per path: prompt tags for one-shot sd-cli, structured `lora` for sd-server.
        loras: Optional[list[tuple[str, float]]] = None,
        # ControlNet is diffusers-only; rejected by the guard below (accepted for parity).
        controlnet: Optional[tuple[str, str, str, float, float, float]] = None,
    ) -> dict[str, Any]:
        import tempfile

        from PIL import Image

        from core.inference import diffusion_lora

        if (
            init_image is not None
            or mask_image is not None
            or reference_images
            or (upscale is not None and upscale > 1)
        ):
            raise ValueError(
                "img2img / inpaint / reference / upscale are not yet supported on the native "
                "sd.cpp engine; run on a GPU (diffusers) for image-conditioned workflows."
            )
        if prompts is not None or seeds is not None:
            raise ValueError(
                "Batched prompt/seed lists are not supported on the native sd.cpp engine "
                "(it renders serially); run on a GPU (diffusers) for batched generation, "
                "or use batch_size for a serial native batch."
            )
        # strength 0/None disables ControlNet (matches diffusers), so no-op it rather than 400.
        if controlnet is not None and controlnet[3] in (None, 0, 0.0):
            controlnet = None
        if controlnet is not None:
            raise ValueError(
                "ControlNet is not yet supported on the native sd.cpp engine; run on a GPU "
                "(diffusers) for ControlNet conditioning."
            )

View on GitHub (pinned to 203007d190)

Solutions

  1. Route image-conditioned requests to the diffusers engine on a GPU host.
  2. Drop init_image/mask_image/reference_images and set upscale<=1 for native text-to-image.
  3. For plain upscaling of a generated image, do a separate post-process step outside the engine.

Example fix

# before (native engine)
backend.generate(prompt='a cat', init_image=img)

# after
backend.generate(prompt='a cat')  # native t2i; use diffusers engine for img2img
Defensive patterns

Strategy: validation

Validate before calling

def is_image_conditioned(init_image, mask_image, reference_images, upscale) -> bool:
    return (init_image is not None or mask_image is not None
            or bool(reference_images) or (upscale is not None and upscale > 1))

if is_image_conditioned(init_image, mask_image, reference_images, upscale):
    route_to_diffusers_engine(request)

Type guard

def is_native_compatible_request(req: dict) -> bool:
    return req.get('init_image') is None and req.get('mask_image') is None \
        and not req.get('reference_images') and (req.get('upscale') or 1) <= 1

Prevention

When it happens

Trigger: generate() on the native engine with init_image, mask_image, non-empty reference_images, or upscale > 1.

Common situations: Hosts without GPU falling back to sd.cpp while the UI still offers inpaint/img2img; API clients reusing a diffusers request payload against the native engine.

Related errors


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