{"record":{"id":"c32d327eb8f45c49","repo":"oracle/graal","slug":"expected-value-kind-but-got","errorCode":null,"errorMessage":"Expected value kind {} but got {}","messagePattern":"Expected value kind (.+?) but got (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":241,"sourceCode":"        var fieldKind = field.getJavaKind();\n\n        if (Modifier.isStatic(reflectionField.getModifiers())) {\n            if (receiver != null) {\n                throw new IllegalArgumentException(\"For static fields, the receiver argument must be null\");\n            }\n        } else if (receiver == null) {\n            throw new NullPointerException(\"For instance fields, the receiver argument must not be null\");\n        } else if (receiver.isNull()) {\n            throw new IllegalArgumentException(\"For instance fields, the receiver argument must not represent a null constant\");\n        }\n\n        Object unboxedValue;\n        if (fieldKind.isObject()) {\n            unboxedValue = snippetReflection.asObject(reflectionField.getType(), value);\n        } else {\n            assert fieldKind.isPrimitive();\n            if (fieldKind != value.getJavaKind()) {\n                throw new IllegalArgumentException(\"Expected value kind \" + fieldKind + \" but got \" + value.getJavaKind());\n            }\n            unboxedValue = value.asBoxedPrimitive();\n        }\n\n        Object unboxedReceiver;\n        if (Modifier.isStatic(reflectionField.getModifiers())) {\n            unboxedReceiver = null;\n        } else {\n            unboxedReceiver = snippetReflection.asObject(reflectionField.getDeclaringClass(), receiver);\n        }\n\n        try {\n            reflectionField.set(unboxedReceiver, unboxedValue);\n        } catch (IllegalAccessException e) {\n            throw new RuntimeException(e);\n        }\n    }\n","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L223-L259","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nResolvedJavaField f = ...;                 // int field\nhostVM.writeField(f, receiver, JavaConstant.forDouble(1.0));  // throws: Expected Int but got Double\n\n// after\nJavaConstant v = switch (f.getJavaKind()) {\n    case Int -> JavaConstant.forInt(1);\n    case Long -> JavaConstant.forLong(1L);\n    case Double -> JavaConstant.forDouble(1.0);\n    default -> throw new AssertionError(f.getJavaKind());\n};\nhostVM.writeField(f, receiver, v);","handlingStrategy":"type-guard","validationCode":"if (field.getJavaKind().isPrimitive() && value.getJavaKind() != field.getJavaKind()) {\n    value = coerce(value, field.getJavaKind()); // explicit conversion\n}","typeGuard":"static boolean kindMatches(ResolvedJavaField f, JavaConstant v) {\n    return !f.getJavaKind().isPrimitive() || f.getJavaKind() == v.getJavaKind();\n}","tryCatchPattern":"catch (IllegalArgumentException e) { re-wrap the value with the forXxx factory for the field's kind }","preventionTips":["Build constants via JavaConstant.forInt/forLong/... keyed on getJavaKind()","Never reuse one numeric constant across differently-typed fields","Regenerate constants after field type changes"],"tags":["graalvm","hostvmaccess","reflection","fields","type-mismatch"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}