jax-ml/jax · error · ValueError

Duplicate serialization registration for type `{nodetype}`.

Error message

Duplicate serialization registration for type `{nodetype}`. Previous registration was with serialized_name `{serialization_registry[nodetype][0]}`.

What it means

jax.experimental.export.register_pytree_node_serialization registers a custom pytree type for serialization under a name. Registering the same Python type twice — e.g. calling the registration decorator/function again (often due to module re-import or notebook re-execution) — raises this ValueError naming the previous serialized_name.

Source

Thrown at jax/_src/export/_export.py:432

    deserialize_auxdata: deserialize the auxdata that was serialized by the
      ``serialize_auxdata``.
    from_children: if present, this is a function that takes that result of
      ``deserialize_auxdata`` along with some children and creates an instance
      of ``nodetype``. This is similar to the ``unflatten_func`` passed to
      :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)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Make registration idempotent: skip if already registered (check the registry before calling)
  2. Use importlib.reload carefully; restart the kernel after editing registration code in notebooks
  3. Consolidate registration into a single module imported once

Example fix

# before
from jax.experimental.export import register_pytree_node_serialization
register_pytree_node_serialization(MyType, 'my_type')  # re-run -> ValueError

# after
from jax.experimental import export
if MyType not in export.serialization_registry:
    register_pytree_node_serialization(MyType, 'my_type')
Defensive patterns

Strategy: validation

Validate before calling

from jax.experimental import export
if MyType not in export.serialization_registry:
    register_pytree_node_serialization(MyType, 'my_type')

Prevention

When it happens

Trigger: Re-running a notebook cell containing @register_pytree_node_serialization(MyType, 'my_type'); re-importing a registration module after importlib.reload; registering the same class in two libraries/plugins.

Common situations: Jupyter/Colab iterative development; hot-reload in web frameworks; two versions of a helper module both performing registration; test suites importing registration code more than once.

Related errors


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