{"record":{"id":"06ae0b81c17e9ed5","repo":"oracle/graal","slug":"input-is-not-an-instance-of-a-registered-class","errorCode":null,"errorMessage":"${input} is not an instance of a registered class.","messagePattern":"(.+?) is not an instance of a registered class\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/RecordingCompilationProxies.java","lineNumber":171,"sourceCode":"\n    @Override\n    public Platform targetPlatform() {\n        return Platform.ofCurrentHost();\n    }\n\n    @Override\n    public DebugCloseable withDebugContext(DebugContext debugContext) {\n        return DebugCloseable.VOID_CLOSEABLE;\n    }\n\n    @Override\n    public CompilationProxy proxify(Object input) {\n        if (input instanceof CompilationProxy compilationProxy) {\n            return compilationProxy;\n        }\n        CompilerInterfaceDeclarations.Registration registration = declarations.findRegistrationForInstance(input);\n        if (registration == null) {\n            throw new IllegalArgumentException(input + \" is not an instance of a registered class.\");\n        }\n        return CompilationProxy.newProxyInstance(registration.clazz(), (proxy, method, callback, args) -> {\n            if (method.equals(CompilationProxyBase.unproxifyMethod)) {\n                return input;\n            }\n            Object[] unproxifiedArgs = (Object[]) unproxifyRecursive(args);\n            CompilerInterfaceDeclarations.MethodStrategy methodStrategy = registration.findStrategy(method);\n            OperationRecorder.RecordedOperationKey key = new OperationRecorder.RecordedOperationKey(input, method, unproxifiedArgs);\n            Object result;\n            if (methodStrategy == CompilerInterfaceDeclarations.MethodStrategy.RecordReplay) {\n                Object resultOrMarker = recorder.getRecordedResultOrMarker(key);\n                if (resultOrMarker instanceof SpecialResultMarker.ExceptionThrownMarker exceptionThrownMarker) {\n                    throw (Throwable) proxifyRecursive(exceptionThrownMarker.getThrown());\n                } else if (resultOrMarker == SpecialResultMarker.NULL_RESULT_MARKER) {\n                    return null;\n                } else if (resultOrMarker != SpecialResultMarker.NO_RESULT_MARKER) {\n                    return proxifyRecursive(resultOrMarker);\n                }","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/RecordingCompilationProxies.java#L153-L189","documentation":"Thrown by RecordingCompilationProxies.proxify when replay-compilation recording is asked to wrap an object whose class was never registered in CompilerInterfaceDeclarations. The recording machinery can only intercept calls on interfaces it knows how to proxy; an unregistered concrete class cannot be proxied, so it fails fast with IllegalArgumentException instead of silently recording nothing.","triggerScenarios":"Calling RecordingCompilationProxies.proxify(Object) with an input that is neither already a CompilationProxy nor an instance of a class registered via CompilerInterfaceDeclarations registration lookup (declarations.findRegistrationForInstance(input) returns null). Typically happens when a new type flows through the compiler interface during -Dgraal.ReplayCompilation recording but its interface was not added to the registered declarations.","commonSituations":"Extending the compiler-interface surface (adding a new implementation class of jdk.vm.ci or Graal interface types) without registering it in CompilerInterfaceDeclarations; version mismatches where a replay/recording branch added a class the declarations table does not know; recording a compilation that touches a rarely used VM-CI implementation class.","solutions":["Register the object's class/interface in CompilerInterfaceDeclarations so findRegistrationForInstance returns non-null, then retry the recording.","If the object should pass through unproxied, check it for CompilationProxy before calling proxify or route it outside the proxy layer.","Update to a GraalVM version where the class is registered (if the class comes from a newer compiler-interface change)."],"exampleFix":"// before\nObject proxy = recordingProxies.proxify(newObject);\n\n// after\nCompilerInterfaceDeclarations.Registration reg = declarations.findRegistrationForInstance(newObject);\nif (reg == null) {\n    // register newObject's interface in CompilerInterfaceDeclarations first\n    throw new IllegalStateException(\"Register \" + newObject.getClass() + \" before recording\");\n}\nObject proxy = recordingProxies.proxify(newObject);","handlingStrategy":"validation","validationCode":"// before proxify, confirm the instance is registrable\nObject input = /* ... */;\nif (!(input instanceof CompilationProxy) &&\n    declarations.findRegistrationForInstance(input) == null) {\n    // do not call proxify; register the class or pass the raw object\n    throw new IllegalStateException(\"Unregistered class for recording: \" + input.getClass());\n}\nCompilationProxy proxy = recordingProxies.proxify(input);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register every compiler-interface implementation class in CompilerInterfaceDeclarations before enabling recording.","Keep recording and compiler-interface changes in the same change set so new classes never bypass registration."],"tags":["graalvm","replay-compilation","proxy","registration"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}