jax-ml/jax · error · ValueError

mode must be one of 'full', 'valid', 'same'; got {mode!r}.

Error message

mode must be one of 'full', 'valid', 'same'; got {mode!r}.

What it means

convolution_matrix accepts only mode='full', 'valid', or 'same' (matching numpy.convolve/np.correlate semantics). Any other value — including 'circ', 'Same', None, or a typo — reaches the ValueError with repr of the bad mode. The comparison is case-sensitive.

Source

Thrown at jax/_src/scipy/linalg.py:2861

    Array([[ 4, -1,  0,  0,  0],
           [-2,  4, -1,  0,  0],
           [ 0, -2,  4, -1,  0],
           [ 0,  0, -2,  4, -1],
           [ 0,  0,  0, -2,  4]], dtype=int32)
  """
  n = operator.index(n)
  if n <= 0:
    raise ValueError(f"n must be a positive integer; got {n}.")
  check_arraylike("convolution_matrix", a)
  a_arr = jnp.asarray(a)
  if a_arr.ndim == 0:
    raise ValueError(
        "convolution_matrix: a must be at least 1-dimensional, got a scalar.")
  m = a_arr.shape[-1]
  if m < 1:
    raise ValueError(f"len(a) must be at least 1; got shape {a_arr.shape}.")
  if mode not in ('full', 'valid', 'same'):
    raise ValueError(
        f"mode must be one of 'full', 'valid', 'same'; got {mode!r}.")
  pad_widths = [(0, 0)] * (a_arr.ndim - 1) + [(0, n - 1)]
  az = jnp.pad(a_arr, pad_widths)
  raz = jnp.pad(jnp.flip(a_arr, axis=-1), pad_widths)
  L = m + n - 1
  if mode == 'same':
    trim = min(n, m) - 1
    tb = trim // 2
    te = trim - tb
  elif mode == 'valid':
    tb = min(n, m) - 1
    te = tb
  else:  # 'full'
    tb = 0
    te = 0
  col0 = lax.slice_in_dim(az, tb, L - te, axis=-1)
  row0 = lax.slice_in_dim(raz, L - n - tb, L - tb, axis=-1)
  return toeplitz(col0, row0)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Use exactly one of 'full', 'valid', 'same' (lowercase)
  2. Normalize user/config input with mode.lower() and whitelist-check before calling
  3. For circular convolution use a different approach (pad+roll or FFT manually)

Example fix

# before
C = convolution_matrix(a, n, mode='circ')
# after
C = convolution_matrix(a, n, mode='full')
Defensive patterns

Strategy: validation

Validate before calling

MODES = ('full', 'valid', 'same')
if mode not in MODES:
    raise ValueError(f'mode must be one of {MODES}, got {mode!r}')
C = convolution_matrix(a, n, mode=mode)

Type guard

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

Try / catch

try:
    convolution_matrix(a, n, mode=mode)
except ValueError as e:
    if 'mode must be one of' in str(e):
        mode = 'full'; convolution_matrix(a, n, mode=mode)
    else: raise

Prevention

When it happens

Trigger: Calling convolution_matrix(a, n, mode='circ'); mode='FULL'; mode=None; mode supplied from config without validation.

Common situations: Confusion with scipy.signal.convolve/convolve2d which accept mode='full','valid','same' too but where users also know boundary= options; passing a mode meant for FFT convolution ('wrap'); porting code that stored mode in a settings dict.

Related errors


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