keras-team/keras · error · ValueError

Unable to serialize {obj} to JSON, because the TypeSpec clas

Error message

Unable to serialize {obj} to JSON, because the TypeSpec class {type(obj)} has not been registered.

What it means

When saving a Keras model to JSON, get_json_type serializes TensorFlow TypeSpec objects (e.g. TensorSpec in an input signature) by looking up a registered serialization name. If the concrete TypeSpec class has no registration, the lookup raises ValueError and this wrapper error names the object and type that failed.

Source

Thrown at keras/src/legacy/saving/json_utils.py:197

    if obj is Ellipsis:
        return {"class_name": "__ellipsis__"}

    # if isinstance(obj, wrapt.ObjectProxy):
    #     return obj.__wrapped__

    if tf.available and isinstance(obj, tf.TypeSpec):
        from tensorflow.python.framework import type_spec_registry

        try:
            type_spec_name = type_spec_registry.get_name(type(obj))
            return {
                "class_name": "TypeSpec",
                "type_spec": type_spec_name,
                "serialized": obj._serialize(),
            }
        except ValueError:
            raise ValueError(
                f"Unable to serialize {obj} to JSON, because the TypeSpec "
                f"class {type(obj)} has not been registered."
            )
    if tf.available and isinstance(obj, tf.__internal__.CompositeTensor):
        spec = tf.type_spec_from_value(obj)
        tensors = []
        for tensor in tf.nest.flatten(obj, expand_composites=True):
            tensors.append((tensor.dtype.name, tensor.numpy().tolist()))
        return {
            "class_name": "CompositeTensor",
            "spec": get_json_type(spec),
            "tensors": tensors,
        }

    if isinstance(obj, enum.Enum):
        return obj.value

    if isinstance(obj, bytes):

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Save with the native format: model.save('model.keras') instead of to_json()
  2. Align keras and tensorflow versions so the spec class is registered
  3. For custom TypeSpecs, register them with TF's TypeSpec serialization registry

Example fix

# before
json_config = model.to_json()
# after
model.save('model.keras')  # native format, no JSON type registry
Defensive patterns

Strategy: fallback

Validate before calling

spec = tf.type_spec_from_value(x)
from tensorflow.python.saved_model import nested_structure_coder
assert spec.__class__ in nested_structure_coder._TYPE_SPEC_TO_CODEC  # crude registry check

Try / catch

try:
    model.to_json()
except ValueError:
    model.save('model.keras')  # fallback to native format

Prevention

When it happens

Trigger: model.to_json() (or any legacy JSON save path) on a model whose config contains an unregistered tf.TypeSpec subclass, e.g. custom ragged/sparse tensor specs or specs from a TF version whose registry does not match Keras.

Common situations: Models with ragged or sparse inputs after a TensorFlow/Keras version mismatch; custom input types introduced by an upgrade.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/05fac86b6be40a6b. Report an issue: GitHub.