jax-ml/jax · error · ValueError

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

Error message

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

What it means

Validation in jax.scipy.signal.fftconvolve: the output-size logic only knows how to crop the full FFT convolution to 'same', 'full', or 'valid' extents. Any other mode string fails this membership check.

Solutions

  1. Use 'full', 'same', or 'valid' exactly
  2. Normalize/validate mode in a config layer

Example fix

# before
signal.fftconvolve(x, y, mode='SAME')
# after
signal.fftconvolve(x, y, 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: Passing mode='circul', mode='Same', or a scipy-unrecognized mode name.

Common situations: Typos and case-sensitivity issues; passing mode through from user settings unvalidated.

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/fa982c66560e852b. Report an issue: GitHub.

Appendix: source

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

    as the first input:

    >>> with jax.numpy.printoptions(precision=3):
    ...   print(jax.scipy.signal.fftconvolve(x, y, mode='same'))
    [3. 6. 7. 6. 3.]

    Specifying ``mode = 'valid'`` returns only the portion where the two arrays
    fully overlap:

    >>> with jax.numpy.printoptions(precision=3):
    ...   print(jax.scipy.signal.fftconvolve(x, y, mode='valid'))
    [6. 7. 6.]
  """
  check_arraylike('fftconvolve', in1, in2)
  in1, in2 = promote_dtypes_inexact(in1, in2)
  if in1.ndim != in2.ndim:
    raise ValueError("in1 and in2 should have the same dimensionality")
  if mode not in ["same", "full", "valid"]:
    raise ValueError("mode must be one of ['same', 'full', 'valid']")
  _fftconvolve = partial(_fftconvolve_unbatched, mode=mode)
  if axes is None:
    return _fftconvolve(in1, in2)
  axes = _ensure_index_tuple(axes)
  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)

View on GitHub (pinned to 1e1c6a8fc0)