{"record":{"id":"035c3575c15287b3","repo":"oracle/graal","slug":"conversionhandler-does-not-implement-the-polyglot","errorCode":null,"errorMessage":"ConversionHandler does not implement the polyglot type conversion interface: com.oracle.truffle.espresso.polyglot.GuestTypeConversion","messagePattern":"ConversionHandler does not implement the polyglot type conversion interface: com\\.oracle\\.truffle\\.espresso\\.polyglot\\.GuestTypeConversion","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/PolyglotTypeMappings.java","lineNumber":128,"sourceCode":"            Symbol<Signature> desc = Signatures.Object_Object;\n\n            // load the GuestTypeConversion interface for type checking\n            Klass conversionInterface = context.getMeta().loadKlassOrNull(context.getTypes().fromClassGetName(GUEST_TYPE_CONVERSION_INTERFACE), bindingsLoader, StaticObject.NULL);\n            if (conversionInterface == null) {\n                throw new IllegalStateException(\"Missing expected guest type conversion interface in polyglot.jar\");\n            }\n\n            for (Map.Entry<String, String> entry : converters) {\n                String type = entry.getKey();\n\n                String conversionHandler = entry.getValue();\n                ObjectKlass conversionKlass = (ObjectKlass) context.getMeta().loadKlassOrNull(context.getTypes().fromClassGetName(conversionHandler), bindingsLoader, StaticObject.NULL);\n                if (conversionKlass == null) {\n                    throw new IllegalStateException(\"Class not found for polyglot type conversion handler: \" + conversionHandler);\n                }\n                // make sure the conversion class implements GuestTypeConversion interface\n                if (!conversionInterface.isAssignableFrom(conversionKlass)) {\n                    throw new IllegalStateException(\"ConversionHandler does not implement the polyglot type conversion interface: \" + GUEST_TYPE_CONVERSION_INTERFACE);\n                }\n                Method conversionMethod = conversionKlass.requireDeclaredMethod(name, desc);\n                StaticObject conversionReceiver = context.getAllocator().createNew(conversionKlass);\n                temp.put(type, new TypeConverterImpl(conversionReceiver, DirectCallNode.create(conversionMethod.getCallTarget())));\n            }\n            typeConverterFunctions = EconomicMap.create(temp);\n        }\n        addInternalConverters(context.getMeta());\n        if (builtinCollections) {\n            EconomicMap<String, ObjectKlass> temp = EconomicMap.create(6);\n            addInternalEspressoCollections(temp, context.getMeta());\n            espressoForeignCollections = EconomicMap.create(temp);\n        }\n    }\n\n    private void addInternalConverters(Meta meta) {\n        EconomicMap<String, InternalTypeConverter> converters = EconomicMap.create(2);\n","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/PolyglotTypeMappings.java#L110-L146","documentation":"Espresso throws this IllegalStateException while initializing polyglot type converters (PolyglotTypeMappings) when a class configured as a conversion handler cannot be assigned to the guest interface com.oracle.truffle.espresso.polyglot.GuestTypeConversion. The handler class is resolved by name from the converters configuration, loaded through the guest class loader, and then checked with conversionInterface.isAssignableFrom. A failure means the configured class exists but is not a valid converter implementation.","triggerScenarios":"Setting the Espresso polyglot type-converter option (a map of type name -> handler class name, e.g. via Context builder or espresso polyglot type converter configuration) where the handler class does not implement com.oracle.truffle.espresso.polyglot.GuestTypeConversion; also pointing the config at a class that only implements an older/incompatible version of the interface, or at an interface/abstract class instead of a concrete implementation.","commonSituations":"Upgrading GraalVM/Espresso where GuestTypeConversion gained methods and an old handler no longer satisfies it; typos or stale fully-qualified class names in the converter configuration; using a handler compiled against a different Espresso version; placing the handler on the wrong classpath so a same-named but wrong class is loaded.","solutions":["Make the configured handler class implement com.oracle.truffle.espresso.polyglot.GuestTypeConversion (implement all its methods) and rebuild.","Verify the fully-qualified class name in the converter configuration matches the actual handler class and that the class is visible to the bindings class loader.","Recompile the handler against the exact GraalVM/Espresso version in use so the interface signature matches.","If the handler was intentionally removed, delete its entry from the converters configuration instead of leaving a stale mapping."],"exampleFix":"// before\npublic final class MyConverter {  // does not implement the guest interface\n    public Object convert(Object v) { return v; }\n}\n// after\npublic final class MyConverter implements com.oracle.truffle.espresso.polyglot.GuestTypeConversion {\n    // implement every method of GuestTypeConversion\n}\n// and ensure the option maps: \"my.Type\" -> \"com.example.MyConverter\"","handlingStrategy":"validation","validationCode":"// before creating the context, check the handler class on the host side\nClass<?> iface = Class.forName(\"com.oracle.truffle.espresso.polyglot.GuestTypeConversion\");\nClass<?> handler = Class.forName(configuredHandlerName);\nif (!iface.isAssignableFrom(handler)) {\n    throw new ConfigurationError(configuredHandlerName + \" must implement \" + iface.getName());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep converter handler implementations in the same build/dependency graph as the GraalVM version being targeted.","Add a startup self-test that loads and assignability-checks every configured converter handler.","Treat converter config as code: version it and re-run the check whenever GraalVM is upgraded."],"tags":["espresso","polyglot","type-conversion","configuration","startup"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}