invoke-ai/InvokeAI · error · ValueError

Unexpected dtype '{dtype}'.

Error message

Unexpected dtype '{dtype}'.

What it means

supports_dtype checks whether the loaded spandrel model supports half, bfloat16, or float32 precision by delegating to the underlying descriptor's supports_* flags. Any dtype outside torch.float16, torch.bfloat16, torch.float32 (e.g. float64, int types) has no mapping and raises ValueError.

Source

Thrown at invokeai/backend/spandrel_image_to_image_model.py:99

        if not isinstance(model, ImageModelDescriptor):
            raise ValueError(
                f"Loaded a spandrel model of type '{type(model)}'. Only image-to-image models are supported "
                "('ImageModelDescriptor')."
            )

        return cls(spandrel_model=model)

    def supports_dtype(self, dtype: torch.dtype) -> bool:
        """Check if the model supports the given dtype."""
        if dtype == torch.float16:
            return self._spandrel_model.supports_half
        elif dtype == torch.bfloat16:
            return self._spandrel_model.supports_bfloat16
        elif dtype == torch.float32:
            # All models support float32.
            return True
        else:
            raise ValueError(f"Unexpected dtype '{dtype}'.")

    def get_model_type_name(self) -> str:
        """The model type name. Intended for logging / debugging purposes. Do not rely on this field remaining
        consistent over time.
        """
        return str(type(self._spandrel_model.model))

    def to(
        self,
        device: Optional[torch.device] = None,
        dtype: Optional[torch.dtype] = None,
        non_blocking: bool = False,
    ) -> None:
        """Note: Some models have limited dtype support. Call supports_dtype(...) to check if the dtype is supported.
        Note: The non_blocking parameter is currently ignored."""
        # TODO(ryand): spandrel.ImageModelDescriptor.to(...) does not support non_blocking. We will have to access the
        # model directly if we want to apply this optimization.
        self._spandrel_model.to(device=device, dtype=dtype)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Only pass torch.float16, torch.bfloat16, or torch.float32 to supports_dtype.
  2. Convert the requested dtype first (e.g. dtype = torch.float16 if dtype not in allowed set).
  3. Check upstream code that derives dtype so it can't produce exotic values.
  4. Catch ValueError and fall back to torch.float32, which all models support.

Example fix

// before
model.supports_dtype(torch.float64)
// after
allowed = {torch.float16, torch.bfloat16, torch.float32}
dtype = dtype if dtype in allowed else torch.float32
model.supports_dtype(dtype)
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = {torch.float16, torch.bfloat16, torch.float32}
if dtype not in SUPPORTED:
    dtype = torch.float32

Type guard

def is_supported_dtype(dtype) -> bool:
    return dtype in {torch.float16, torch.bfloat16, torch.float32}

Try / catch

try:
    ok = model.supports_dtype(dtype)
except ValueError:
    ok = model.supports_dtype(torch.float32)  # universal fallback

Prevention

When it happens

Trigger: Calling supports_dtype(dtype) with a dtype other than torch.float16/bfloat16/float32, typically from _load_model when converting the model to an unexpected precision.

Common situations: Passing dtype strings ('fp16') instead of torch dtype objects; config or variant plumbing delivering torch.float64 or a quantized dtype; custom code selecting dtype = latents.dtype when latents are not a float16/32 type.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/90d7d354987e26e4. Report an issue: GitHub.