oracle/graal · error · GraalError

Failed to find a Class object for %s. This can be fixed by a

Error message

Failed to find a Class object for %s. This can be fixed by adding %s.class to ReplayTypeSupport#KNOWN_CLASSES.

What it means

Thrown by ReplayTypeSupport.classCast during replay deserialization when a replay file references a Class whose name is not in the KNOWN_CLASSES table, so it was decoded as a ClassSurrogate placeholder. When the codec actually needs a real Class object (not just name-based matching), the surrogate cannot be cast and GraalError tells you to extend KNOWN_CLASSES.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/ReplayTypeSupport.java:141

            return primitiveClass;
        }
        Class<?> knownClass = KNOWN_CLASSES.get(name);
        if (knownClass != null) {
            return knownClass;
        }
        return new ClassSurrogate(name);
    }

    /**
     * Casts a deserialized object to a {@link Class}.
     *
     * @param clazz the deserialized class object or surrogate
     * @return the class object cast to the requested type
     */
    @SuppressWarnings("unchecked")
    static <C> Class<C> classCast(Object clazz) {
        if (clazz instanceof ClassSurrogate(String name)) {
            throw new GraalError(String.format("Failed to find a Class object for %s. This can be fixed by adding %s.class to ReplayTypeSupport#KNOWN_CLASSES.", name, name));
        }
        return (Class<C>) clazz;
    }

    /**
     * Determines the enum element type that should be recorded for an {@link EnumSet}.
     *
     * @param enumSet the enum set whose element type should be determined
     * @return the element type to serialize for the enum set
     */
    static Class<?> enumSetElementType(EnumSet<?> enumSet) {
        Optional<?> maybeElementType = enumSet.stream().findAny();
        if (maybeElementType.isPresent()) {
            return ((Enum<?>) maybeElementType.get()).getDeclaringClass();
        }
        maybeElementType = EnumSet.complementOf(enumSet).stream().findAny();
        if (maybeElementType.isPresent()) {
            return ((Enum<?>) maybeElementType.get()).getDeclaringClass();

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Add the missing class (e.g. MyType.class) to the KNOWN_CLASSES array in ReplayTypeSupport.createKnownClasses and rebuild.
  2. Regenerate the replay file with a build whose KNOWN_CLASSES covers the classes the compilation actually touches.
  3. Ensure recording and replay run on the same GraalVM/compiler version so the class set matches.

Example fix

// before
Class<?>[] classes = { JavaKind.class, ResolvedJavaMethod.class, /* ... */ };

// after
Class<?>[] classes = { JavaKind.class, ResolvedJavaMethod.class,
                jdk.vm.ci.meta.MyNewType.class, /* ... */ };
Defensive patterns

Strategy: validation

Type guard

// detect a surrogate before casting
Object decoded = ReplayTypeSupport.decodeClass(name);
if (decoded.getClass().getSimpleName().equals("ClassSurrogate")) {
    // class not in KNOWN_CLASSES: add it before replay will work
}

Try / catch

try {
    Class<?> c = ReplayTypeSupport.classCast(decoded);
} catch (GraalError e) {
    if (e.getMessage().contains("KNOWN_CLASSES")) {
        // extract the class name and add it to ReplayTypeSupport.KNOWN_CLASSES
    }
    throw e;
}

Prevention

When it happens

Trigger: Replaying a recorded compilation whose data contains a Class constant not listed in ReplayTypeSupport.KNOWN_CLASSES (table built in createKnownClasses: CPUFeature enums, JavaKind, HotSpotResolved* types, etc.). decodeClass returns a ClassSurrogate, and a later classCast of that surrogate throws. The check is skipped inside libgraal (image) builds; it fires in non-image runtimes.

Common situations: A new kind of Class constant starts flowing through the compiler interface between the recording and replaying builds (e.g. a new VM-CI meta type or arch feature enum); recording and replaying with different GraalVM versions; adding a new field of type Class to a recorded compiler-interface object.

Related errors


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