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

  1. Choose a unique, namespaced serialized_name like 'mylib.MyType'
  2. Reuse the existing registration (import the type that already owns the name) instead of re-registering
  3. 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

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


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