jax-ml/jax · error · TypeError
concatenate expects at least one operand, got 0.
Error message
concatenate expects at least one operand, got 0.
What it means
Raised by JAX's internal concatenate shape-checking rule when lax.concatenate (and APIs built on it like jnp.concatenate) is called with an empty operand list. JAX needs at least one array to infer ndim and result shape, so zero operands is a TypeError at trace time.
Source
Thrown at jax/_src/lax/lax.py:7231
sharding_rule=_clamp_sharding_rule,
vma_rule=partial(core.standard_vma_rule, 'clamp'))
ad.defjvp(clamp_p,
lambda g, min, operand, max:
select(bitwise_and(gt(min, operand), lt(min, max)),
g, _zeros(operand)),
lambda g, min, operand, max:
select(bitwise_and(gt(operand, min), lt(operand, max)),
g, _zeros(operand)),
lambda g, min, operand, max:
select(lt(max, operand), g, _zeros(operand)))
batching.primitive_batchers[clamp_p] = _clamp_batch_rule
mlir.register_lowering(clamp_p, partial(_nary_lower_hlo, hlo.clamp))
def _concatenate_shape_rule(*operands, **kwargs):
dimension = kwargs.pop('dimension')
if not operands:
msg = "concatenate expects at least one operand, got 0."
raise TypeError(msg)
if not all(isinstance(operand, ShapedArray) for operand in operands):
msg = "All objects to concatenate must be arrays, got {}."
op = next(op for op in operands if not isinstance(op, ShapedArray))
raise TypeError(msg.format(type(op)))
if len({operand.ndim for operand in operands}) != 1:
msg = "Cannot concatenate arrays with different numbers of dimensions: got {}."
raise TypeError(msg.format(", ".join(str(o.shape) for o in operands)))
if not 0 <= dimension < operands[0].ndim:
msg = "concatenate dimension out of bounds: dimension {} for shapes {}."
raise TypeError(msg.format(dimension, ", ".join([str(o.shape) for o in operands])))
shapes = [operand.shape[:dimension] + operand.shape[dimension+1:]
for operand in operands]
if shapes[:-1] != shapes[1:]:
msg = ("Cannot concatenate arrays with shapes that differ in dimensions "
"other than the one being concatenated: concatenating along "
"dimension {} for shapes {}.")
shapes = [operand.shape for operand in operands]
raise TypeError(msg.format(dimension, ", ".join(map(str, shapes))))View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Ensure the list of arrays is non-empty before concatenating: guard with `if arrays:` and provide a default/zero-length array of the right ndim
- If empty input is legitimate, construct the result shape explicitly, e.g. jnp.zeros((0, feat_dim)) instead of concatenating nothing
- Check upstream code that produced the list (loops, filters, dataset iteration) for off-by-one or empty-input cases
Example fix
// before out = jnp.concatenate([x for x in batch if keep(x)], axis=0) // after parts = [x for x in batch if keep(x)] out = jnp.concatenate(parts, axis=0) if parts else jnp.zeros((0, feat_dim))
Defensive patterns
Strategy: validation
Validate before calling
if not arrays:
out = jnp.zeros((0,) + trailing_shape)
else:
out = jnp.concatenate(arrays, axis=0) Type guard
def non_empty_arrays(xs) -> bool:
return len(xs) > 0 and all(hasattr(x, 'shape') for x in xs) Prevention
- Never concatenate unconditionally on filtered/loop-built lists; check emptiness first
- Standardize an empty-batch representation (e.g. shape (0, feat)) in data pipelines
When it happens
Trigger: Calling jnp.concatenate([]) or jax.lax.concatenate([], dimension=0); building an operand list in a loop/filter that ends up empty.
Common situations: Dynamically collecting arrays to concat (e.g. filtering batches) where the filter removes everything; refactoring a list comprehension so it can return [].
Related errors
- Cannot concatenate arrays with different numbers of dimensio
- concatenate dimension out of bounds: dimension {} for shapes
- Cannot concatenate arrays with shapes that differ in dimensi
- stack expects at least one operand, got 0.
- scan got `length` argument of {} which disagrees with leadin
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/9f303d0ba191ec7e.
Report an issue: GitHub.