jax-ml/jax · error · TypeError
stop_gradient only works on valid JAX arrays, but input argu
Error message
stop_gradient only works on valid JAX arrays, but input argument is: {x} What it means
FromPickle found a node tuple whose size is not the expected 6 elements. A pickled PyTreeDef stream is corrupt or was produced by an incompatible serialization format/version.
Source
Thrown at jax/_src/ad_util.py:99
return f'Zero({self.aval})'
def instantiate(self):
return zeros_like_aval(self.aval)
register_pytree_node(Zero, lambda z: ((), z.aval), lambda aval, _: Zero(aval))
def p2tz(primal_value):
return Zero(typeof(primal_value).to_tangent_aval())
def p2cz(primal_value):
return Zero(typeof(primal_value).to_ct_aval())
def a2tz(primal_aval):
return Zero(primal_aval.to_tangent_aval())
def _stop_gradient_impl[T](x: T) -> T:
if not core.valid_jaxtype(x):
raise TypeError("stop_gradient only works on valid JAX arrays, but "
f"input argument is: {x}")
return x
stop_gradient_p : Primitive = Primitive('stop_gradient')
stop_gradient_p.def_impl(_stop_gradient_impl)
stop_gradient_p.def_abstract_eval(lambda x: x)
# User-facing version of `Zero`
class SymbolicZero:
def __init__(self, aval: core.AbstractValue) -> None:
self.aval = aval
def __repr__(self) -> str:
return self.__class__.__name__
# TODO(mattjj,frostig): this forwards attr lookup to self.aval delegate;
# should dedup with core.Tracer.__getattr__ which does the same thingView on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Re-save the pickle with the currently running jaxlib version
- Verify the pickle payload integrity (checksum/size) before loading
- Avoid hand-editing pickled treedefs; recompute structures from data
Example fix
# before treedef = pickle.loads(old_checkpoint['treedef']) # from older jaxlib # after # regenerate: _, treedef = jax.tree_util.tree_flatten(fresh_params)
Defensive patterns
Strategy: fallback
Validate before calling
import jax # check pickle payload shape before unpickling where possible # simplest: wrap unpickle and fall back to regeneration
Try / catch
try:
treedef = pickle.loads(data)
except Exception as e:
if 'Malformed pickled PyTreeDef' in str(e):
_, treedef = jax.tree_util.tree_flatten(fresh_reference_obj)
else:
raise Prevention
- Save jaxlib version alongside pickled treedefs
- Regenerate structures from data rather than unpickling when versions differ
- Checksum checkpoint files
When it happens
Trigger: Unpickling a PyTreeDef whose __getstate__ payload contains tuples of length != 6, e.g. hand-crafted pickles or pickles from a different jaxlib version with a different node format.
Common situations: Loading checkpoints/saved states across jaxlib versions; truncated or manually edited pickle data; pickle protocol incompatibilities.
Related errors
- The names should be exclusive and should not intersect in `n
- {self.__class__.__name__} has no attribute {name}
- Could not find type: %s.
- Malformed pickled PyTreeDef, expected 2-tuple
- Malformed pickled SequenceKey, expected 1-tuple
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/15a4732cf29572ca.
Report an issue: GitHub.