oracle/graal · error · IllegalArgumentException
Expected value kind {} but got {}
Error message
Expected value kind {} but got {} What it means
Thrown by HostVMAccess.writeField when storing to a primitive-typed field with a value constant whose JavaKind differs from the field's kind (e.g. putting a double constant into an int field). The host VM will not silently coerce primitive kinds on field stores; object-typed fields bypass this check and go through asObject instead.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:241
var fieldKind = field.getJavaKind();
if (Modifier.isStatic(reflectionField.getModifiers())) {
if (receiver != null) {
throw new IllegalArgumentException("For static fields, the receiver argument must be null");
}
} else if (receiver == null) {
throw new NullPointerException("For instance fields, the receiver argument must not be null");
} else if (receiver.isNull()) {
throw new IllegalArgumentException("For instance fields, the receiver argument must not represent a null constant");
}
Object unboxedValue;
if (fieldKind.isObject()) {
unboxedValue = snippetReflection.asObject(reflectionField.getType(), value);
} else {
assert fieldKind.isPrimitive();
if (fieldKind != value.getJavaKind()) {
throw new IllegalArgumentException("Expected value kind " + fieldKind + " but got " + value.getJavaKind());
}
unboxedValue = value.asBoxedPrimitive();
}
Object unboxedReceiver;
if (Modifier.isStatic(reflectionField.getModifiers())) {
unboxedReceiver = null;
} else {
unboxedReceiver = snippetReflection.asObject(reflectionField.getDeclaringClass(), receiver);
}
try {
reflectionField.set(unboxedReceiver, unboxedValue);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Match the constant kind to the field kind exactly: use JavaConstant.forInt/forLong/forDouble/... per field.getJavaKind()
- Derive the constant from field.getJavaKind() dynamically instead of hardcoding
- After changing a field's type, regenerate or update every constant produced for it
Example fix
// before
ResolvedJavaField f = ...; // int field
hostVM.writeField(f, receiver, JavaConstant.forDouble(1.0)); // throws: Expected Int but got Double
// after
JavaConstant v = switch (f.getJavaKind()) {
case Int -> JavaConstant.forInt(1);
case Long -> JavaConstant.forLong(1L);
case Double -> JavaConstant.forDouble(1.0);
default -> throw new AssertionError(f.getJavaKind());
};
hostVM.writeField(f, receiver, v); Defensive patterns
Strategy: type-guard
Validate before calling
if (field.getJavaKind().isPrimitive() && value.getJavaKind() != field.getJavaKind()) {
value = coerce(value, field.getJavaKind()); // explicit conversion
} Type guard
static boolean kindMatches(ResolvedJavaField f, JavaConstant v) {
return !f.getJavaKind().isPrimitive() || f.getJavaKind() == v.getJavaKind();
} Try / catch
catch (IllegalArgumentException e) { re-wrap the value with the forXxx factory for the field's kind } Prevention
- Build constants via JavaConstant.forInt/forLong/... keyed on getJavaKind()
- Never reuse one numeric constant across differently-typed fields
- Regenerate constants after field type changes
When it happens
Trigger: Calling writeField where fieldKind.isPrimitive() and value.getJavaKind() != fieldKind — e.g. JavaConstant.forDouble(1.0) for an int field, forInt for a long field, or passing a boxed-object constant for a primitive field.
Common situations: Reusing one value constant across several fields of different kinds in a loop; signature/kind drift after a field type change (int -> long) while constant builders still emit the old kind; generic serialization code mapping JSON/schema numbers to a single numeric kind.
Related errors
- Illegal argument type: arguments[{}] of type {} could not be
- Illegal argument type: receiver of type {} could not be conv
- For static fields, the receiver argument must be null
- For instance fields, the receiver argument must not be null
- For instance fields, the receiver argument must not represen
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/c32d327eb8f45c49.
Report an issue: GitHub.