deepset-ai/haystack · error · ValueError

Invalid component device type

Error message

Invalid component device type '{type(device).__name__}'. Must either be None or ComponentDevice.

What it means

resolve_device() validates that the `device` argument is either None or a ComponentDevice instance. Passing any other type (str, torch.device, int, etc.) triggers this ValueError, since Haystack cannot infer how to map arbitrary objects onto its device abstraction.

Solutions

  1. Convert the value with ComponentDevice.from_str("cuda:0") before passing it.
  2. If you have multiple devices, use ComponentDevice.from_multiple(DeviceMap.from_dict(...)).
  3. Pass None explicitly to let Haystack resolve the default device.

Example fix

// before
resolved = resolve_device("cuda:0")
// after
from haystack.utils import ComponentDevice
resolved = resolve_device(ComponentDevice.from_str("cuda:0"))
Defensive patterns

Strategy: type-guard

Validate before calling

from haystack.utils import ComponentDevice
assert device is None or isinstance(device, ComponentDevice), f"bad device: {type(device)}"

Type guard

def is_component_device(d) -> bool:
    return d is None or isinstance(d, ComponentDevice)

Try / catch

try:
    resolved = resolve_device(device)
except ValueError:
    resolved = resolve_device(None)

Prevention

When it happens

Trigger: Calling resolve_device() with a raw string like "cuda:0", a torch.device object, an int, or any non-ComponentDevice value.

Common situations: Migrating from older Haystack versions where plain strings were accepted; passing a HF/torch device object directly; constructing a pipeline component config manually.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/34283fbd1399c023. Report an issue: GitHub.

Appendix: source

Thrown at haystack/utils/device.py:447

        if self._single_device is not None:
            return self.from_single(self._single_device)

        assert self._multiple_devices is not None
        assert self._multiple_devices.first_device is not None
        return self.from_single(self._multiple_devices.first_device)

    @staticmethod
    def resolve_device(device: Optional["ComponentDevice"] = None) -> "ComponentDevice":
        """
        Select a device for a component. If a device is specified, it's used. Otherwise, the default device is used.

        :param device:
            The provided device, if any.
        :returns:
            The resolved device.
        """
        if not isinstance(device, ComponentDevice) and device is not None:
            raise ValueError(
                f"Invalid component device type '{type(device).__name__}'. Must either be None or ComponentDevice."
            )

        if device is None:
            device = ComponentDevice.from_single(_get_default_device())

        return device

    def to_dict(self) -> dict[str, Any]:
        """
        Convert the component device representation to a JSON-serializable dictionary.

        :returns:
            The dictionary representation.
        """
        if self._single_device is not None:
            return {"type": "single", "device": str(self._single_device)}
        if self._multiple_devices is not None:

View on GitHub (pinned to e318778c9b)