jax-ml/jax · error · TypeError

the `static_argnums` argument to `jax.checkpoint` / `jax.rem

Error message

the `static_argnums` argument to `jax.checkpoint` / `jax.remat` must be an int, tuple of ints or, bool, but got value {static_argnums}

What it means

After rebuilding a structure, UnflattenImpl verifies the supplied leaf iterator was fully consumed; leftover leaves mean more leaves were passed than the treedef contains, raising 'Too many leaves for PyTreeDef; expected %d.'

Source

Thrown at jax/_src/ad_checkpoint.py:427


def remat(fun: Callable, *, prevent_cse: bool = True,
          policy: Callable[..., bool] | None = None,
          static_argnums: int | tuple[int, ...] = ()) -> Callable:
  """Alias of :func:`jax.checkpoint`."""
  return checkpoint(fun, prevent_cse=prevent_cse, policy=policy,
                    static_argnums=static_argnums)

# This function is similar to api_util.argnums_partial, except the error
# messages are specific to jax.remat (and thus more actionable), the
# hashing/caching behavior is slightly different, and this function accepts a
# boolean for static_argnums. Perhaps the two could be de-duplicated.
def _remat_static_argnums(fun, static_argnums, args):
  if type(static_argnums) is int:
    static_argnums = (static_argnums,)
  elif not (type(static_argnums) is tuple and
            all(type(d) is int for d in static_argnums)):
    raise TypeError("the `static_argnums` argument to `jax.checkpoint` / "
                    "`jax.remat` must be an int, tuple of ints or, bool, but "
                    f"got value {static_argnums}")

  if not all(-len(args) <= d < len(args) for d in static_argnums):
    raise ValueError("the `static_argnums` argument to `jax.checkpoint` / "
                     "`jax.remat` can only take integer values greater than or "
                     "equal to `-len(args)` and less than `len(args)`, but got "
                     f"{static_argnums}, while `len(args)` = {len(args)}")

  if not static_argnums:
    return fun, args
  nargs = len(args)
  static_argnums_ = frozenset(d % len(args) for d in static_argnums)
  dyn_args, static_args = [], []
  for i, x in enumerate(args):
    if i in static_argnums_: static_args.append(WrapHashably(x))
    else: dyn_args.append(x)
  new_fun = _dyn_args_fun(fun, static_argnums_, tuple(static_args), nargs)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Slice leaves to the expected count: treedef.unflatten(leaves[:treedef.num_leaves]) only after verifying that is semantically correct
  2. Prefer jax.tree.unflatten over manual leaf list surgery; derive leaves with the same treedef
  3. Validate len(leaves) == treedef.num_leaves before the call
  4. Use jax.tree.map to redistribute values instead of concatenating leaf lists

Example fix

# before
all_leaves = leaves_a + leaves_b
out = treedef_a.unflatten(all_leaves)  # too many leaves

# after
out = treedef_a.unflatten(leaves_a)
out_b = treedef_b.unflatten(leaves_b)
Defensive patterns

Strategy: validation

Validate before calling

n = treedef.num_leaves
assert len(leaves) == n, f'{len(leaves)} leaves supplied, treedef holds {n}'
out = treedef.unflatten(leaves)

Try / catch

try:
    out = treedef.unflatten(leaves)
except ValueError as e:
    if 'Too many leaves' in str(e):
        leaves = leaves[:treedef.num_leaves]  # only if truncation is intended
        out = treedef.unflatten(leaves)
    else:
        raise

Prevention

When it happens

Trigger: treedef.unflatten(leaves) / jax.tree.unflatten with len(leaves) > treedef.num_leaves: duplicating leaves (e.g. vstack of leaves), concatenating leaf lists from multiple structures, or unflattening a longer flat array without slicing to num_leaves.

Common situations: Broadcasting one pytree's leaves into another's structure; stacking params from several devices and unflattening the concatenated list; using leaves from a bigger tree with a smaller treedef after filtering the treedef instead of the leaves.

Related errors


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