jax-ml/jax · error · ValueError

scan got no values to scan over and `length` not provided.

Error message

scan got no values to scan over and `length` not provided.

What it means

scan was called with no xs values at all (empty pytree or None) and no explicit length, so there is nothing from which to infer the number of iterations and it raises ValueError.

Source

Thrown at jax/_src/lax/control_flow/loops.py:525

    except core.ConcretizationTypeError:
      msg = ('The `length` argument to `scan` expects a concrete `int` value.'
             ' For scan-like iteration with a dynamic length, use `while_loop`'
             ' or `fori_loop`.')
      raise core.ConcretizationTypeError(length, msg) from None
    else:
      if not all(length == l for l in lengths):
        msg = ("scan got `length` argument of {} which disagrees with "
              "leading axis sizes {}.")
        raise ValueError(msg.format(length, [x.shape[0] for x in xs_flat]))
      return length
  else:
    unique_lengths = set(lengths)
    if len(unique_lengths) > 1:
      msg = "scan got values with different leading axis sizes: {}."
      raise ValueError(msg.format(', '.join(str(x.shape[0]) for x in xs_flat)))
    elif len(unique_lengths) == 0:
      msg = "scan got no values to scan over and `length` not provided."
      raise ValueError(msg)
    else:
      return list(unique_lengths)[0]

def _capitalize(s):
  # s.capitalize() converts s[1:] to lowercase which we don't want.
  return s[0].capitalize() + s[1:]

def _check_carry_type(name, body_fun, in_carry, out_carry):
  try:
    sig = inspect.signature(body_fun)
  except (ValueError, TypeError):
    sig = None
  carry_name = sig and list(sig.parameters)[0]
  if carry_name:
    component = lambda p: (f'the input carry component {carry_name}{keystr(p)}'
                           if p else f'the input carry {carry_name}')
  else:
    component = lambda p: (f'the input carry at path {keystr(p)}'

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pass an explicit length: lax.scan(f, init, xs=None, length=n_steps)
  2. Use lax.fori_loop(0, n, body, init) for data-free loops
  3. Provide dummy xs of shape (n,) if downstream code expects ys

Example fix

// before
carry, ys = lax.scan(lambda c, _: (c + 1, c), 0)
// after
carry, ys = lax.scan(lambda c, _: (c + 1, c), 0, length=n_steps)
Defensive patterns

Strategy: validation

Validate before calling

flat = jax.tree_util.tree_leaves(xs)
if not flat:
    assert length is not None, 'must pass length when xs is empty/None'

Type guard

def scan_args_valid(xs, length) -> bool:
    return bool(jax.tree_util.tree_leaves(xs)) or length is not None

Try / catch

null

Prevention

When it happens

Trigger: lax.scan(f, init) or lax.scan(f, init, None) without length; xs being an empty tuple/list.

Common situations: Running a fixed-iteration loop with no per-step data but forgetting length; refactoring a loop's data away without adding length=n.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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