jax-ml/jax · error · ValueError

For 'valid' mode, One input must be at least as large as the

Error message

For 'valid' mode, One input must be at least as large as the other in every dimension.

What it means

For mode='valid', one input must dominate the other in every dimension (s1 >= s2 or s1 <= s2 consistently) so that a well-defined overlap region exists. Mixed ordering (bigger in one dim, smaller in another) is rejected.

Source

Thrown at jax/_src/scipy/signal.py:129

  axes = tuple(canonicalize_axis(ax, in1.ndim) for ax in axes)
  mapped_axes = set(range(in1.ndim)) - set(axes)
  if any(in1.shape[i] != in2.shape[i] for i in mapped_axes):
    raise ValueError(f"mapped axes must have same shape; got {in1.shape=} {in2.shape=} {axes=}")
  for ax in sorted(mapped_axes):
    _fftconvolve = api.vmap(_fftconvolve, in_axes=ax, out_axes=ax)
  return _fftconvolve(in1, in2)

def _fftconvolve_unbatched(in1: Array, in2: Array, mode: str) -> Array:
  full_shape = tuple(s1 + s2 - 1 for s1, s2 in zip(in1.shape, in2.shape))

  # TODO(jakevdp): potentially use next_fast_len to evaluate with a more efficient shape.
  fft_shape = full_shape  # tuple(next_fast_len(s) for s in full_shape)

  if mode == 'valid':
    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("For 'valid' mode, One input must be at least as "
                       "large as the other in every dimension.")
    if swap:
      in1, in2 = in2, in1

  if (all(s1 == 1 or s2 == 1 for s1, s2 in zip(in1.shape, in2.shape))):
    conv = in1 * in2
  else:
    if jnp.iscomplexobj(in1):
      fft, ifft = jnp.fft.fftn, jnp.fft.ifftn
    else:
      fft, ifft = jnp.fft.rfftn, jnp.fft.irfftn
    sp1 = fft(in1, fft_shape)
    sp2 = fft(in2, fft_shape)
    conv = ifft(sp1 * sp2, fft_shape)

  if mode == "full":
    out_shape = full_shape
  elif mode == "same":

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pad the smaller input so one operand dominates everywhere, or crop the larger one
  2. Switch to mode='same' or 'full' if valid semantics aren't required
  3. Verify kernel size <= input size per axis before calling

Example fix

# before
signal.fftconvolve(img, kernel, mode='valid')  # img (10,3), kernel (4,5)
# after
img = jnp.pad(img, ((0,0),(0,2)))  # now (10,5)
signal.fftconvolve(img, kernel, mode='valid')
Defensive patterns

Strategy: validation

Validate before calling

ok = all(s1 >= s2 for s1,s2 in zip(in1.shape,in2.shape)) or all(s1 <= s2 for s1,s2 in zip(in1.shape,in2.shape))
assert ok

Type guard

def valid_mode_valid(a, b) -> bool:
    return all(x >= y for x, y in zip(a.shape, b.shape)) or all(x <= y for x, y in zip(a.shape, b.shape))

Prevention

When it happens

Trigger: fftconvolve of shapes (10, 3) and (4, 5): first input larger in dim0 but smaller in dim1.

Common situations: 2D filters where kernel size exceeds image size in one axis; mis-sized padding producing inconsistent shapes.

Related errors


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