{"record":{"id":"a81528476ce65024","repo":"jax-ml/jax","slug":"zero-size-arrays-not-supported-in-convolutions-go","errorCode":null,"errorMessage":"zero-size arrays not supported in convolutions, got shapes {in1.shape} and {in2.shape}.","messagePattern":"zero-size arrays not supported in convolutions, got shapes (.+?) and (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/signal.py","lineNumber":168,"sourceCode":"    out_shape = tuple(s1 - s2 + 1 for s1, s2 in zip(in1.shape, in2.shape))\n  else:\n    raise ValueError(f\"Unrecognized {mode=}\")\n\n  start_indices = tuple((full_size - out_size) // 2\n                        for full_size, out_size in zip(full_shape, out_shape))\n  return lax.dynamic_slice(conv, start_indices, out_shape)\n\n\n# Note: we do not reuse the code from jax.numpy.convolve here, because the handling\n# of padding differs slightly between the two implementations (particularly for\n# mode='same').\ndef _convolve_nd(in1: Array, in2: Array, mode: ModeString, *, precision: PrecisionLike) -> Array:\n  if mode not in [\"full\", \"same\", \"valid\"]:\n    raise ValueError(\"mode must be one of ['full', 'same', 'valid']\")\n  if in1.ndim != in2.ndim:\n    raise ValueError(\"in1 and in2 must have the same number of dimensions\")\n  if in1.size == 0 or in2.size == 0:\n    raise ValueError(f\"zero-size arrays not supported in convolutions, got shapes {in1.shape} and {in2.shape}.\")\n  in1, in2 = promote_dtypes_inexact(in1, in2)\n\n  no_swap = all(s1 >= s2 for s1, s2 in zip(in1.shape, in2.shape))\n  swap = all(s1 <= s2 for s1, s2 in zip(in1.shape, in2.shape))\n  if not (no_swap or swap):\n    raise ValueError(\"One input must be smaller than the other in every dimension.\")\n\n  shape_o = in2.shape\n  if swap:\n    in1, in2 = in2, in1\n  shape = in2.shape\n  in2 = jnp.flip(in2)\n\n  if mode == 'valid':\n    padding = [(0, 0) for s in shape]\n  elif mode == 'same':\n    padding = [(s - 1 - (s_o - 1) // 2, s - s_o + (s_o - 1) // 2)\n               for (s, s_o) in zip(shape, shape_o)]","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/signal.py#L150-L186","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nout = jax.scipy.signal.convolve(x[mask], kernel, mode='same')\n// after\nsub = x[mask]\nout = jax.scipy.signal.convolve(sub, kernel, mode='same') if sub.size else jnp.zeros_like(sub)","handlingStrategy":"validation","validationCode":"def safe_conv(in1, in2, mode='full'):\n    if in1.size == 0 or in2.size == 0:\n        return None  # or a zero array of the expected output shape\n    return jax.scipy.signal.convolve(in1, in2, mode=mode)","typeGuard":"def is_nonempty(arr) -> bool:\n    return jnp.asarray(arr).size > 0","tryCatchPattern":null,"preventionTips":["Assert .size > 0 on data-derived arrays before convolution","Log shapes of dynamic slices when masks are involved"],"tags":["jax","scipy","convolution","empty-array","shape-validation"],"backgroundTag":"empty-array-argument","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}