jax-ml/jax · error · ValueError

jax.numpy.block does not allow empty list arguments

Error message

jax.numpy.block does not allow empty list arguments

What it means

The nested list passed to jnp.block must not contain an empty list at any level. _block recurses into sublists and raises this ValueError when it encounters one of length zero, because an empty block has no shape and cannot be concatenated.

Source

Thrown at jax/_src/numpy/lax_numpy.py:4996

    arr = clip(a, 0, N - 1)
  else:
    raise ValueError(f"mode={mode!r} not understood. Must be 'raise', 'wrap', or 'clip'")

  arr, *choices = broadcast_arrays(arr, *choices)
  return array(choices)[(arr,) + indices(arr.shape, sparse=True)]


def _atleast_nd(x: ArrayLike, n: int) -> Array:
  m = np.ndim(x)
  return lax.broadcast(x, (1,) * (n - m)) if m < n else asarray(x)

def _block(xs: ArrayLike | list[Any]) -> tuple[Array, int]:
  if isinstance(xs, tuple):
    raise ValueError("jax.numpy.block does not allow tuples, got {}"
                     .format(xs))
  elif isinstance(xs, list):
    if len(xs) == 0:
      raise ValueError("jax.numpy.block does not allow empty list arguments")
    xs_tup, depths = unzip2([_block(x) for x in xs])
    if any(d != depths[0] for d in depths[1:]):
      raise ValueError("Mismatched list depths in jax.numpy.block")
    rank = max(depths[0], max(np.ndim(x) for x in xs_tup))
    xs_tup = tuple(_atleast_nd(x, rank) for x in xs_tup)
    return concatenate(xs_tup, axis=-depths[0]), depths[0] + 1
  else:
    return asarray(xs), 1


@export
@api.jit
def block(arrays: ArrayLike | list[Any]) -> Array:
  """Create an array from a list of blocks.

  JAX implementation of :func:`numpy.block`.

  Args:

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Guard block construction: skip or pad empty groups before calling jnp.block
  2. Check for empty sublists: if any(len(sub) == 0 for sub in blocks): handle fallback
  3. Build the array with jnp.concatenate/stack with explicit empty handling instead

Example fix

// before
out = jnp.block([row for row in rows])  # some row may be []
// after
rows = [r for r in rows if len(r) > 0]
out = jnp.block(rows) if rows else jnp.zeros((0,))
Defensive patterns

Strategy: validation

Validate before calling

def has_no_empty(blocks):
    return isinstance(blocks, list) and all(
        len(b) > 0 and (not isinstance(b, list) or has_no_empty(b)) for b in blocks)
assert has_no_empty(blocks)

Prevention

When it happens

Trigger: jnp.block([[], []]), jnp.block([[a], []]), or any programmatically built nested list where a filter/comprehension produced an empty inner list.

Common situations: Dynamically assembled blocks where a condition excludes all elements of one row/column (e.g. [[x for x in row if keep(x)] for row in rows] with an empty result), often under varying batch conditions.

Related errors


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