oracle/graal · error · IllegalArgumentException

Cannot serialize result marker ${instance}

Error message

Cannot serialize result marker ${instance}

What it means

ResultMarkerSerializer serializes SpecialResultMarker values that indicate what a recorded method call produced: NO_RESULT_MARKER, NULL_RESULT_MARKER, or ExceptionThrownMarker. Serialize() throws IllegalArgumentException when the instance is none of these — an unrecognized result-marker subtype reached the codec.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java:517

        }

        @Override
        public String tag() {
            return "marker";
        }

        @Override
        public void serialize(Object instance, JsonBuilder.ObjectBuilder objectBuilder, RecursiveSerializer serializer) throws IOException {
            String type;
            if (instance == SpecialResultMarker.NO_RESULT_MARKER) {
                type = "noResult";
            } else if (instance == SpecialResultMarker.NULL_RESULT_MARKER) {
                type = "null";
            } else if (instance instanceof SpecialResultMarker.ExceptionThrownMarker thrownMarker) {
                type = "exception";
                serializer.serialize(thrownMarker.getThrown(), objectBuilder.append("throwable"));
            } else {
                throw new IllegalArgumentException("Cannot serialize result marker " + instance);
            }
            objectBuilder.append("type", type);
        }

        @Override
        public Object deserialize(EconomicMap<String, Object> json, RecursiveDeserializer deserializer, CompilationProxies.ProxyFactory proxyFactory) throws DeserializationException {
            switch ((String) json.get("type")) {
                case "noResult" -> {
                    return SpecialResultMarker.NO_RESULT_MARKER;
                }
                case "null" -> {
                    return SpecialResultMarker.NULL_RESULT_MARKER;
                }
                case "exception" -> {
                    return new SpecialResultMarker.ExceptionThrownMarker((Throwable) deserializer.deserialize(json.get("throwable"), proxyFactory));
                }
                case null, default -> throw new DeserializationException(this, json, "Invalid marker type.");
            }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Check instance.getClass() in a debugger to identify the unknown marker subtype
  2. Add a branch to serialize() plus the mirror 'type' case in deserialize() in JsonReplayCodec.java:517
  3. Re-record the replay file with the build you serialize on so marker types match

Example fix

// before
else { throw new IllegalArgumentException("Cannot serialize result marker " + instance); }
// after
else if (instance instanceof SpecialResultMarker.MyMarker m) {
    type = "myMarker";
    serializer.serialize(m.payload(), objectBuilder.append("payload"));
}
else { throw new IllegalArgumentException("Cannot serialize result marker " + instance); }
Defensive patterns

Strategy: type-guard

Type guard

static boolean isSupportedResultMarker(Object m) {
    return m == SpecialResultMarker.NO_RESULT_MARKER
        || m == SpecialResultMarker.NULL_RESULT_MARKER
        || m instanceof SpecialResultMarker.ExceptionThrownMarker;
}

Prevention

When it happens

Trigger: A new SpecialResultMarker subtype is introduced (e.g. to encode 'result elided by filter' or lazy results) and the serializer switch is not updated; or a corrupted/proxied marker object of the wrong class is passed during serialization.

Common situations: GraalVM version drift where the recording side produces a marker type the serializing side cannot name; custom OperationRecorder implementations returning ad-hoc marker objects.

Related errors


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