jax-ml/jax · error · nb::value_error
get_topology_for_devices requires >= 1 devices.
Error message
get_topology_for_devices requires >= 1 devices.
What it means
Constructing a topology from a device list is only meaningful with at least one device; an empty list gives no client or platform to derive the topology from, so the binding validates input and throws.
Source
Thrown at jaxlib/jax.cc:621
const absl::flat_hash_map<std::string, xla::PjRtValueType>& options)
-> std::shared_ptr<xla::ifrt::Topology> {
if (c_api.name() == nullptr ||
std::string_view(c_api.name()) != "pjrt_c_api") {
throw nb::value_error(
"Argument to get_c_api_topology was not a pjrt_c_api capsule.");
}
if (c_api.data() == nullptr) {
throw nb::value_error(
"Argument to get_c_api_topology contained a null pointer.");
}
return std::make_shared<xla::ifrt::PjRtTopology>(xla::ValueOrThrow(
xla::GetCApiTopology(static_cast<const PJRT_Api*>(c_api.data()),
topology_name, options)));
});
m.def("get_topology_for_devices",
[](const std::vector<nb_class_ptr<PyDevice>>& py_devices) {
if (py_devices.empty()) {
throw nb::value_error(
"get_topology_for_devices requires >= 1 devices.");
}
auto client = py_devices[0]->client();
absl::InlinedVector<xla::ifrt::Device*, 1> ifrt_devices;
ifrt_devices.reserve(py_devices.size());
for (const auto& py_device : py_devices) {
if (py_device->client().get() != client.get()) {
throw nb::value_error(
"devices passed to get_topology_for_devices come from "
"different clients.");
}
ifrt_devices.push_back(py_device->device());
}
xla::ifrt::DeviceListRef device_list = xla::ValueOrThrow(
client->ifrt_client()->MakeDeviceList(ifrt_devices));
return xla::ValueOrThrow(
client->ifrt_client()->GetTopologyForDevices(device_list));
});View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Check the list is non-empty before calling; debug why it's empty
- Verify process/device slicing logic in multi-process jax jobs
Example fix
# before jaxlib.get_topology_for_devices(my_devices) # after assert my_devices, 'no devices assigned to this process' jaxlib.get_topology_for_devices(my_devices)
Defensive patterns
Strategy: validation
Validate before calling
assert devices, 'need >= 1 device'
Type guard
def has_devices(devs) -> bool:
return len(devs) > 0 Prevention
- Validate per-process device slices in multi-host jobs
When it happens
Trigger: jaxlib.get_topology_for_devices([]) — typically because the devices list was built from an empty slice, wrong device filter, or a filtering bug.
Common situations: Multi-process code slicing jax.devices() per process and accidentally producing an empty list (e.g. wrong process index).
Related errors
- Argument to get_c_api_topology was not a pjrt_c_api capsule.
- {full_name} must be a pytree prefix with bool leaves or a tu
- The devices() method was called on {self._error_repr()}.{sel
- Axes mentioned in `manual_axis_type` field of ShapedArray sh
- varying and unreduced cannot have common mesh axes. Got vary
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/24c67eb18303d389.
Report an issue: GitHub.