jax-ml/jax · error · ValueError

zero-size array to reduction operation {self.__name__} which

Error message

zero-size array to reduction operation {self.__name__} which has no identity

What it means

Reducing an empty (zero-size) array requires an identity or initial value to produce a well-defined result. In the scan-based fallback, if the leading reduced dimension is 0 and no initial is supplied, JAX raises this ValueError.

Source

Thrown at jax/_src/numpy/ufunc_api.py:298

      if where is not None:
        where = where.ravel()
      axis = 0
    else:
      axis = canonicalize_axis(axis, arr.ndim)
      if keepdims:
        final_shape = (*arr.shape[:axis], 1, *arr.shape[axis + 1:])
      else:
        final_shape = (*arr.shape[:axis], *arr.shape[axis + 1:])

    # TODO: handle without transpose?
    if axis != 0:
      arr = _moveaxis(arr, axis, 0)
      if where is not None:
        where = _moveaxis(where, axis, 0)

    if arr.shape[0] == 0:
      if initial is None:
        raise ValueError(f"zero-size array to reduction operation {self.__name__} which has no identity")
      return lax.full(final_shape, initial, dtype)

    def body_fun(i, val):
      if where is None:
        return self(val, arr[i].astype(dtype))
      else:
        return _where(where[i], self(val, arr[i].astype(dtype)), val)

    start_value: ArrayLike
    if initial is None:
      start_index = 1
      start_value = arr[0]
    else:
      start_index = 0
      start_value = initial
    start_value = _broadcast_to(lax.asarray(start_value).astype(dtype), arr.shape[1:])

    result = control_flow.fori_loop(start_index, arr.shape[0], body_fun, start_value)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pass an explicit initial value
  2. Guard upstream: skip the reduction when arr.shape[axis] == 0 and use a sensible default
  3. Ensure data pipelines never produce empty inputs unexpectedly

Example fix

// before
result = jnp.maximum.reduce(x)  # x.shape[0] == 0
// after
result = jnp.maximum.reduce(x, initial=-jnp.inf)
Defensive patterns

Strategy: validation

Validate before calling

if x.shape[axis if isinstance(axis,int) else 0] == 0:
    result = initial if initial is not None else raise_safe_default()

Try / catch

try:
    r = u.reduce(x)
except ValueError:
    r = initial  # e.g. -jnp.inf for maximum

Prevention

When it happens

Trigger: jnp.maximum.reduce(jnp.zeros((0,3))) or any ufunc.reduce over an empty axis without initial, where the ufunc has no usable identity.

Common situations: Empty batches after filtering, dynamic data loading that yields zero rows, edge cases in dataloaders feeding reductions.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/39e134f3a94f8717. Report an issue: GitHub.