oracle/graal · error · IllegalArgumentException

No serializer for :

Error message

No serializer for  : 

What it means

Thrown by BinaryReplayCodec.writeValue when an object being serialized is of a class that has no Registration in CompilerInterfaceDeclarations and matches none of the codec's built-in tag cases. The binary replay format can only encode registered types (singletons or registered instances) plus a fixed set of primitives, arrays, and well-known compiler types. Any other class hits the terminal 'No serializer for <class>: <value>' IllegalArgumentException.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/BinaryReplayCodec.java:812

                if (value == ValueKind.Illegal) {
                    out.write(SPECIAL_SINGLETON_TAG);
                    out.writePackedUnsignedInt(SINGLETON_ILLEGAL_VALUE_KIND);
                    return;
                }
                CompilerInterfaceDeclarations.Registration registration = declarations.isRegisteredClassInstance(value) ? declarations.findRegistrationForInstance(value) : null;
                if (registration != null) {
                    int registrationIndex = registrationIndex(registration);
                    if (registration.singleton()) {
                        out.write(REGISTERED_SINGLETON_TAG);
                        out.writePackedUnsignedInt(registrationIndex);
                    } else {
                        out.write(REGISTERED_INSTANCE_TAG);
                        out.writePackedUnsignedInt(registrationIndex);
                        out.writePackedUnsignedInt(state.instanceId(registrationIndex, value));
                    }
                    return;
                }
                throw new IllegalArgumentException("No serializer for " + value.getClass() + ": " + value);
            }
        }
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    private static Object readValue(ObjectCopierInputStream in, ReadState state) throws IOException {
        int tag = in.read();
        if (tag < 0) {
            throw new EOFException();
        }
        return switch (tag) {
            case NULL_TAG -> null;
            case FALSE_TAG -> false;
            case TRUE_TAG -> true;
            case BYTE_TAG -> in.readByteValue();
            case SHORT_TAG -> in.readShort();
            case INT_TAG -> in.readPackedSignedInt();
            case LONG_TAG -> in.readPackedSignedLong();

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Register the offending class (and its supertype mapping) with CompilerInterfaceDeclarations so the codec can emit REGISTERED_* tags for it
  2. If the type is under your control, add an explicit TAG case to writeValue/readValue in the codec
  3. Serialize the offending data as a simpler representable form (String, primitive, or registered wrapper) before it reaches the copier

Example fix

// before
Object value = new MyCustomType(); // not registered
writeValue(out, value, state); // -> No serializer for ...

// after
// register the type so the codec recognizes it
declarations.register(MyCustomType.class, /* singleton= */ false);
writeValue(out, value, state); // emits REGISTERED_INSTANCE_TAG
Defensive patterns

Strategy: validation

Validate before calling

boolean serializable(Object v, CompilerInterfaceDeclarations d) {
    if (v == null || v instanceof String || v instanceof Number || v instanceof Boolean || v.getClass().isArray()) return true;
    return d.findRegistration(v.getClass()) != null;
}

Try / catch

try {
    codec.writeValues(values);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("No serializer for")) {
        throw new IllegalStateException("Unregistered type in recorded state: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Recording a compilation whose inputs/results reference a type not covered by CompilerInterfaceDeclarations registrations or the codec's hardcoded switch cases; adding a new field to a recorded compiler object whose type is unregistered.

Common situations: Extending the compiler with new value types that flow into recorded compilation state without registering them; replay support lagging behind a new feature that introduces novel object types.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/f0dfe66a94ddfa1e. Report an issue: GitHub.