jax-ml/jax · error · ValueError
Duplicate serialization registration for serialized_name `{s
Error message
Duplicate serialization registration for serialized_name `{serialized_name}`. Previous registration was for type `{deserialization_registry[serialized_name][0]}`. What it means
The companion check to 518: a different Python type was previously registered under the same serialized_name, so registering a new type with that name would make deserialization ambiguous. The error names the type that already owns the name.
Source
Thrown at jax/_src/export/_export.py:437
:func:`jax.tree_util.register_pytree_node`. If not present, we look up
and use the ``unflatten_func``. This is needed for ``collections.namedtuple``,
which does not have a ``register_pytree_node``, but it can be useful to
override that function. Note that the result of ``from_children`` is
only used with :func:`jax.tree_util.tree_structure` to construct a proper
PyTree node, it is not used to construct the outputs of the serialized
function.
Returns:
the same type passed as ``nodetype``, so that this function can
be used as a class decorator.
"""
if nodetype in serialization_registry:
raise ValueError(
f"Duplicate serialization registration for type `{nodetype}`. "
"Previous registration was with serialized_name "
f"`{serialization_registry[nodetype][0]}`.")
if serialized_name in deserialization_registry:
raise ValueError(
"Duplicate serialization registration for "
f"serialized_name `{serialized_name}`. "
"Previous registration was for type "
f"`{deserialization_registry[serialized_name][0]}`.")
if from_children is None:
if nodetype not in tree_util._registry:
raise ValueError(
f"If `from_children` is not present, you must call first"
f"`jax.tree_util.register_pytree_node` for `{nodetype}`")
from_children = tree_util._registry[nodetype].from_iter
serialization_registry[nodetype] = (
serialized_name, serialize_auxdata)
deserialization_registry[serialized_name] = (
nodetype, deserialize_auxdata, from_children)
return nodetype
View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Choose a unique, namespaced serialized_name like 'mylib.MyType'
- Reuse the existing registration (import the type that already owns the name) instead of re-registering
- If you renamed a class intentionally, keep the old registration for backward compatibility and register the new class under a new name
Example fix
# before register_pytree_node_serialization(NewType, 'FrozenDict') # name taken # after register_pytree_node_serialization(NewType, 'mylib.NewType')
Defensive patterns
Strategy: validation
Validate before calling
from jax.experimental import export
name_taken = 'my_type' in export.deserialization_registry
if name_taken and export.deserialization_registry['my_type'][0] is not MyType:
raise RuntimeError('serialized name collision; pick a namespaced name') Prevention
- Namespace serialized names: 'mylib.TypeName'
- Register each wire name exactly once across the whole dependency tree
- When renaming classes, assign a new serialized name rather than reusing the old one
When it happens
Trigger: Registering class B with serialized_name 'my_type' when class A already used 'my_type'; name collisions between your registration and one made by a framework (e.g. a library also registering 'FrozenDict'); renaming classes but keeping the serialized name for compatibility.
Common situations: Two dependencies claiming the same serialized name; versioned class hierarchies where old and new classes share a wire name; copy-pasted registration code across modules.
Related errors
- Duplicate serialization registration for type `{nodetype}`.
- No VJP is available
- serializing DisabledSafetyCheck: {check}
- the rematted computation's closure contains a mutable array
- Effects not supported in partial-eval of `checkpoint`/`remat
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/c6519bcbc20446cd.
Report an issue: GitHub.