jax-ml/jax · error · ValueError

zero-size array to reduction operation {name} which has no i

Error message

zero-size array to reduction operation {name} which has no identity

What it means

A reduction without an identity element (e.g. max/min) was applied to a zero-size array: some axis being reduced over has length 0, so there is no element to produce a result and no neutral value to fall back on.

Source

Thrown at jax/_src/numpy/reductions.py:130

  # object methods. For example `np.sum(x)` will call `x.sum()` if the `sum()` method
  # exists, passing along all its arguments.
  if out is not None:
    raise NotImplementedError(f"The 'out' argument to jnp.{name} is not supported.")
  a = ensure_arraylike(name, a)
  where_ = check_where(name, where_)
  axis = core.concrete_or_error(None, axis, f"axis argument to jnp.{name}().")

  if initial is None and not has_identity and where_ is not None:
    raise ValueError(f"reduction operation {name} does not have an identity, so to use a "
                     f"where mask one has to specify 'initial'")

  a = preproc(a) if preproc else a
  pos_dims, dims = _reduction_dims(a, axis)

  if initial is None and not has_identity:
    shape = np.shape(a)
    if not _all(shape[d] >= 1 for d in pos_dims):
      raise ValueError(f"zero-size array to reduction operation {name} which has no identity")

  result_dtype: DType
  if dtype is None:
    result_dtype = a.dtype
    if promote_integers:
      result_dtype = _promote_integer_dtype(result_dtype)
  else:
    result_dtype = dtypes.check_and_canonicalize_user_dtype(dtype, name)

  if upcast_f16_for_computation and dtypes.issubdtype(result_dtype, np.inexact):
    computation_dtype = _upcast_f16(result_dtype)
  else:
    computation_dtype = result_dtype
  a = lax.convert_element_type(a, computation_dtype)
  op = op if computation_dtype != np.bool_ else bool_op
  # NB: in XLA, init_val must be an identity for the op, so the user-specified
  # initial value must be applied afterward.
  init_val = _reduction_init_val(a, init_val)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Check shapes before reducing: assert all(s > 0 for s in shape)
  2. Supply initial: jnp.max(x, axis=0, initial=-jnp.inf)
  3. Use a reduction with identity (sum returns 0, any/all have identities) where semantics permit

Example fix

// before
m = jnp.max(filtered, axis=0)
// after
m = jnp.max(filtered, axis=0, initial=-jnp.inf) if filtered.size else default_val
Defensive patterns

Strategy: validation

Validate before calling

import jax.numpy as jnp
if any(s == 0 for s in jnp.shape(x)):
    result = default  # skip empty reduction
else:
    result = jnp.max(x, axis=0)

Prevention

When it happens

Trigger: jnp.max(jnp.zeros((0, 3)), axis=0); dynamically-shaped data that becomes empty after filtering/slicing; reductions over an empty batch dimension under jit with concrete shapes.

Common situations: Empty batches in training loops after filtering; slicing to nothing (x[x > 100] when nothing matches) then reducing; padding code producing zero-length axes.

Related errors


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