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

  1. Match the constant kind to the field kind exactly: use JavaConstant.forInt/forLong/forDouble/... per field.getJavaKind()
  2. Derive the constant from field.getJavaKind() dynamically instead of hardcoding
  3. 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

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


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/c32d327eb8f45c49. Report an issue: GitHub.