{"record":{"id":"3d60b5a0e35376e1","repo":"oracle/graal","slug":"constant-has-unexpected-type-3d60b5","errorCode":null,"errorMessage":"Constant has unexpected type {}: {}","messagePattern":"Constant has unexpected type (.+?): (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java","lineNumber":419,"sourceCode":"        return lookupType(name, systemClassLoader);\n    }\n\n    @Override\n    public ResolvedJavaType lookupPlatformClassLoaderType(String name) {\n        return lookupType(name, platformClassLoader);\n    }\n\n    @Override\n    public ResolvedJavaType lookupBootClassLoaderType(String name) {\n        return lookupType(name, JavaConstant.NULL_POINTER);\n    }\n\n    @Override\n    public ResolvedJavaModule getModule(ResolvedJavaType type) {\n        JavaConstant originalClass = providers.getConstantReflection().asJavaClass(type);\n        JavaConstant module = invoke(java_lang_Class_getModule, originalClass);\n        if (!(module instanceof EspressoExternalObjectConstant espressoConstant)) {\n            throw new IllegalArgumentException(\"Constant has unexpected type \" + module.getClass() + \": \" + module);\n        }\n        Value value = espressoConstant.getValue();\n        return new EspressoExternalResolvedJavaModule(this, value);\n    }\n\n    @Override\n    public ResolvedJavaPackage getPackage(ResolvedJavaType type) {\n        JavaConstant originalClass = providers.getConstantReflection().asJavaClass(type);\n        JavaConstant pkg = invoke(java_lang_Class_getPackage, originalClass);\n        if (!(pkg instanceof EspressoExternalObjectConstant espressoConstant)) {\n            throw new IllegalArgumentException(\"Constant has unexpected type \" + pkg.getClass() + \": \" + pkg);\n        }\n        Value value = espressoConstant.getValue();\n        return new EspressoExternalResolvedJavaPackage(this, value);\n    }\n\n    @Override\n    public ResolvedJavaModuleLayer bootModuleLayer() {","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java#L401-L437","documentation":"EspressoExternalVMAccess.getModule(type) mirrors java.lang.Class.getModule inside the guest Espresso VM and wraps the returned module in a EspressoExternalResolvedJavaModule. If the constant reflection layer returns a JavaConstant that is not an EspressoExternalObjectConstant (i.e. it originated from a foreign JVMCI backend), the wrapper cannot extract the guest Value and throws IllegalArgumentException.","triggerScenarios":"Passing a ResolvedJavaType from a different JVMCI provider (HotSpot resolved type, or a type from another Espresso context) to getModule(); the intermediate asJavaClass/invoke then yields a foreign constant that fails the instanceof EspressoExternalObjectConstant check.","commonSituations":"Compiler plugins or substitutions that mix host and guest meta-access providers; polyglot embeddings with multiple Espresso contexts; refactors that route types through the wrong providers instance.","solutions":["Only call getModule() on ResolvedJavaType instances created by the same EspressoExternalVMAccess (check vmAccess.owns(type) if available).","Route types from other providers through their own module accessor instead.","Ensure the constant reflection provider in providers is the Espresso one, not a delegating host provider."],"exampleFix":"// before\nResolvedJavaModule m = vmAccess.getModule(someType);\n\n// after\nif (vmAccess.owns(someType)) {\n    ResolvedJavaModule m = vmAccess.getModule(someType);\n} else {\n    ResolvedJavaModule m = otherProvider.getModule(someType);\n}","handlingStrategy":"type-guard","validationCode":"if (!vmAccess.owns(type)) {\n    // resolve module via the type's own provider instead\n}","typeGuard":"static boolean ownsType(EspressoExternalVMAccess access, ResolvedJavaType t) {\n    return access.owns(t);\n}","tryCatchPattern":"catch (IllegalArgumentException e) { log foreign type and rethrow — mixing providers here usually indicates a design bug, not a runtime condition. }","preventionTips":["Thread a single providers instance through the whole resolution pipeline.","Assert owns(type) in debug builds at API boundaries.","Avoid caching ResolvedJavaType across contexts."],"tags":["jvmci","espresso","graalvm","modules","constants"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}