jax-ml/jax · error · ValueError

mode must be one of ['full', 'same', 'valid']

Error message

mode must be one of ['full', 'same', 'valid']

What it means

Guard in the internal _convolve_nd helper (backing convolve/convolve2d/correlate2d): after computing the full convolution it selects the output extent by mode, and only 'full', 'same', 'valid' are recognized. Any other mode string falls to the else branch and raises.

Solutions

  1. Use exact lowercase strings 'full'/'same'/'valid'
  2. Sanitize mode strings from configs early

Example fix

# before
signal.convolve2d(a, b, mode='Same')
# after
signal.convolve2d(a, b, mode='same')
Defensive patterns

Strategy: validation

Validate before calling

assert mode in ('full','same','valid'), mode

Type guard

def is_mode(m: str) -> bool: return m in ('full', 'same', 'valid')

Prevention

When it happens

Trigger: convolve2d(x, y, mode='same ' ), correlate2d(..., mode='Valid'), or a mode from an unvalidated config.

Common situations: Typos/case; passing numpy string types or enum objects from other frameworks.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


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

Appendix: source

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

    out_shape = full_shape
  elif mode == "same":
    out_shape = in1.shape
  elif mode == "valid":
    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':

View on GitHub (pinned to 1e1c6a8fc0)