jax-ml/jax · error · ValueError
zero-size arrays not supported in convolutions, got shapes {
Error message
zero-size arrays not supported in convolutions, got shapes {in1.shape} and {in2.shape}. What it means
Raised by jax.scipy.signal._convolve_nd when either input array to a convolution/correlation has zero elements (size 0). JAX's convolution implementation is backed by lax.conv_general_dilated, which cannot handle empty tensors, unlike some SciPy paths. The message reports both input shapes so you can see which operand is empty.
Source
Thrown at jax/_src/scipy/signal.py:168
out_shape = tuple(s1 - s2 + 1 for s1, s2 in zip(in1.shape, in2.shape))
else:
raise ValueError(f"Unrecognized {mode=}")
start_indices = tuple((full_size - out_size) // 2
for full_size, out_size in zip(full_shape, out_shape))
return lax.dynamic_slice(conv, start_indices, out_shape)
# Note: we do not reuse the code from jax.numpy.convolve here, because the handling
# of padding differs slightly between the two implementations (particularly for
# mode='same').
def _convolve_nd(in1: Array, in2: Array, mode: ModeString, *, precision: PrecisionLike) -> Array:
if mode not in ["full", "same", "valid"]:
raise ValueError("mode must be one of ['full', 'same', 'valid']")
if in1.ndim != in2.ndim:
raise ValueError("in1 and in2 must have the same number of dimensions")
if in1.size == 0 or in2.size == 0:
raise ValueError(f"zero-size arrays not supported in convolutions, got shapes {in1.shape} and {in2.shape}.")
in1, in2 = promote_dtypes_inexact(in1, in2)
no_swap = all(s1 >= s2 for s1, s2 in zip(in1.shape, in2.shape))
swap = all(s1 <= s2 for s1, s2 in zip(in1.shape, in2.shape))
if not (no_swap or swap):
raise ValueError("One input must be smaller than the other in every dimension.")
shape_o = in2.shape
if swap:
in1, in2 = in2, in1
shape = in2.shape
in2 = jnp.flip(in2)
if mode == 'valid':
padding = [(0, 0) for s in shape]
elif mode == 'same':
padding = [(s - 1 - (s_o - 1) // 2, s - s_o + (s_o - 1) // 2)
for (s, s_o) in zip(shape, shape_o)]View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Check in1.size > 0 and in2.size > 0 before calling and skip/handle empty batches explicitly
- Fix upstream slicing/masking logic that produced the zero-size array
- If an empty result is semantically valid, return a correctly-shaped zero array instead of calling convolve
Example fix
// before out = jax.scipy.signal.convolve(x[mask], kernel, mode='same') // after sub = x[mask] out = jax.scipy.signal.convolve(sub, kernel, mode='same') if sub.size else jnp.zeros_like(sub)
Defensive patterns
Strategy: validation
Validate before calling
def safe_conv(in1, in2, mode='full'):
if in1.size == 0 or in2.size == 0:
return None # or a zero array of the expected output shape
return jax.scipy.signal.convolve(in1, in2, mode=mode) Type guard
def is_nonempty(arr) -> bool:
return jnp.asarray(arr).size > 0 Prevention
- Assert .size > 0 on data-derived arrays before convolution
- Log shapes of dynamic slices when masks are involved
When it happens
Trigger: Calling jax.scipy.signal.convolve, convolve2d, correlate, or correlate2d with an empty array, e.g. jnp.zeros((0, 5)) or jnp.array([]), or with a shape containing a 0 dimension produced by slicing/boolean masking.
Common situations: Dynamic slicing or filtering that occasionally yields zero rows before convolution; edge cases in batch processing where a batch is empty; empty kernels constructed from data-driven sizes.
Related errors
- convolve2d() only supports 2-dimensional inputs.
- conv_general_dilated batch_group_count must divide lhs batch
- conv_general_dilated rhs output feature dimension size must
- conv_general_dilated window and window_strides must have the
- Wrong number of explicit pads for convolution: expected {},
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/a81528476ce65024.
Report an issue: GitHub.