oracle/graal · error · IllegalArgumentException
Constant has unexpected type {}: {}
Error message
Constant has unexpected type {}: {} What it means
Thrown by the EspressoExternalResolvedJavaModule constructor when the polyglot Value passed in is not an instance of guest java.lang.Module (checked via getMetaObject().getMetaQualifiedName()). The adapter dereferences the Value's meta-object immediately and builds a ResolvedJavaModule wrapper around it, so a Value of any other guest type (Class, ModuleLayer, String, null-meta foreign object) fails construction. This guards the boundary where arbitrary interop Values enter the JVMCI type system.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaModule.java:44
import java.util.Objects;
import java.util.Set;
import org.graalvm.polyglot.TypeLiteral;
import org.graalvm.polyglot.Value;
import jdk.graal.compiler.vmaccess.ResolvedJavaModule;
import jdk.graal.compiler.vmaccess.ResolvedJavaModuleLayer;
final class EspressoExternalResolvedJavaModule implements ResolvedJavaModule {
private final EspressoExternalVMAccess access;
private final String name;
final Value moduleValue;
EspressoExternalResolvedJavaModule(EspressoExternalVMAccess access, Value moduleValue) {
// j.l.Module?
if (!"java.lang.Module".equals(moduleValue.getMetaObject().getMetaQualifiedName())) {
throw new IllegalArgumentException("Constant has unexpected type " + moduleValue.getMetaObject().getMetaQualifiedName() + ": " + moduleValue);
}
this.access = access;
this.moduleValue = moduleValue;
this.name = access.java_lang_Module_getName.getMirror().execute(moduleValue).asString();
}
@Override
public ResolvedJavaModuleLayer getLayer() {
Value layer = moduleValue.invokeMember("getLayer");
return layer.isNull() ? null : new EspressoExternalResolvedJavaModuleLayer(access, layer);
}
@Override
public String getName() {
return name;
}
@OverrideView on GitHub (pinned to a66e9ccd1d)
Solutions
- Check value.getMetaObject().getMetaQualifiedName().equals("java.lang.Module") before constructing/looking up the module
- Handle null meta-object (foreign/host Values) by mapping the object into the Espresso guest context first
- If the Value came from getLayer()/ModuleLayer APIs, unwrap the actual module members instead of passing the layer
Example fix
// before
ResolvedJavaModule m = access.findModule(someValue);
// after
if (someValue.getMetaObject() == null ||
!"java.lang.Module".equals(someValue.getMetaObject().getMetaQualifiedName())) {
throw new IllegalArgumentException("not a guest java.lang.Module: " + someValue);
}
ResolvedJavaModule m = access.findModule(someValue); Defensive patterns
Strategy: type-guard
Validate before calling
Value meta = moduleValue.getMetaObject();
if (meta == null || !"java.lang.Module".equals(meta.getMetaQualifiedName())) {
throw new IllegalArgumentException("not a guest java.lang.Module: " + moduleValue);
} Type guard
boolean isGuestModule(Value v) {
Value meta = v.getMetaObject();
return meta != null && "java.lang.Module".equals(meta.getMetaQualifiedName());
} Prevention
- Validate the meta-object qualified name before passing any Value into module lookups
- Handle null meta-objects (foreign/host Values) by mapping into the Espresso guest context first
- Do not feed ModuleLayer Values or Class Values where a Module is expected
When it happens
Trigger: Calling whatever API produced this wrapper (module lookup in EspressoExternalVMAccess) with a Value obtained from a Class.getModule() on a primitive/array class, a ModuleLayer Value, or a host object mapped with asValue(...) that has a host meta-object with a different qualified name.
Common situations: Module-aware lookups over classes loaded by the bootstrap loader (unnamed module handling), polyglot context configuration where host meta-objects differ from guest ones, and version changes in how the access layer resolves modules.
Related errors
- Expected an espresso object receiver, got {}
- Bad argument kind at index {}: expected Object, got {} wrapp
- Expected an EspressoExternalResolvedJavaModule, got {}
- Cannot bind label to negative position %d
- Out of scratch registers: %s
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/4dad823cf20584ae.
Report an issue: GitHub.