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
- Slice leaves to the expected count: treedef.unflatten(leaves[:treedef.num_leaves]) only after verifying that is semantically correct
- Prefer jax.tree.unflatten over manual leaf list surgery; derive leaves with the same treedef
- Validate len(leaves) == treedef.num_leaves before the call
- 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
- Never concatenate leaf lists from different treedefs
- Slice flat arrays to num_leaves (or use index_util) before unflatten
- Prefer jax.tree.map over manual leaf-list plumbing
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
- prevent_cse must be a bool or tuple of bools, got {type(prev
- numpy masked arrays are not supported as direct inputs to JA
- Python int {value} too large to convert to int64
- Python int {value} too large to convert to int32
- The names should be exclusive and should not intersect in `n
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/d5e9f60d7e3f35c8.
Report an issue: GitHub.