{"record":{"id":"e102b6a73528b4ad","repo":"oracle/graal","slug":"element-should-be-a-but-was","errorCode":null,"errorMessage":"Element {} should be a {} but was {}","messagePattern":"Element (.+?) should be a (.+?) but was (.+?)","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":552,"sourceCode":"        EspressoResolvedJavaType elementalType = arrayType.getElementalType();\n        Value array;\n        boolean isPrimitiveArray;\n        int dimensions = arrayType.getDimensions();\n        if (elementalType instanceof EspressoExternalResolvedInstanceType elementalInstanceType) {\n            array = invokeJVMCIHelper(\"newObjectArray\", elementalInstanceType.getMetaObject(), dimensions, elements.length);\n            isPrimitiveArray = false;\n        } else {\n            JavaKind javaKind = elementalType.getJavaKind();\n            assert javaKind.isPrimitive() && javaKind != JavaKind.Void;\n            array = invokeJVMCIHelper(\"newPrimitiveArray\", (int) javaKind.getTypeChar(), dimensions, elements.length);\n            isPrimitiveArray = dimensions == 1;\n        }\n        if (isPrimitiveArray) {\n            JavaKind javaKind = elementalType.getJavaKind();\n            for (int i = 0; i < elements.length; i++) {\n                JavaConstant element = elements[i];\n                if (javaKind != element.getJavaKind()) {\n                    throw new IllegalArgumentException(\"Element \" + i + \" should be a \" + javaKind + \" but was \" + element.getJavaKind());\n                }\n                if (element.isDefaultForKind()) {\n                    continue;\n                }\n                array.setArrayElement(i, element.asBoxedPrimitive());\n            }\n        } else {\n            for (int i = 0; i < elements.length; i++) {\n                JavaConstant element = elements[i];\n                if (element.isNull()) {\n                    continue;\n                }\n                if (!(element instanceof EspressoExternalObjectConstant objectElement)) {\n                    throw new IllegalArgumentException(\"Element \" + i + \" should be an espresso object constant, got \" + safeGetClass(element));\n                }\n                try {\n                    array.setArrayElement(i, objectElement.getValue());\n                } catch (ClassCastException e) {","sourceCodeStart":534,"sourceCodeEnd":570,"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#L534-L570","documentation":"While filling a guest primitive array in asArrayConstant, each element's JavaKind must exactly match the array's elemental kind (an int[] element must be JavaKind.Int, etc.). A mismatch throws IllegalArgumentException naming the index, expected kind, and actual kind. This mirrors Java's strict array-store typing for primitives, where no implicit primitive widening happens.","triggerScenarios":"Passing elements[i] with a different JavaKind than the component type — e.g. JavaConstant.forFloat(...) into an int[] (multi-dimensional primitive arrays with dimensions > 1 take object elements and go down the other branch), or boxed/object constants into a 1-D primitive array.","commonSituations":"Auto-generated constant-array code that assumes int/long interchangeability; elements produced by asBoxedPrimitive or forObject that carry Object kind; refactor changing an array's component type without updating the element constants.","solutions":["Create each element with the constant factory matching the component kind: JavaConstant.forInt/forLong/forDouble/... so kinds line up.","Validate kinds in a loop before calling asArrayConstant when elements come from external input.","Re-check the component type (including dimensions) after refactors of the array being built."],"exampleFix":"// before\nJavaConstant[] elems = {JavaConstant.forFloat(1.5f)};\nvmAccess.asArrayConstant(intType, elems); // int[] vs Float kind\n\n// after\nJavaConstant[] elems = {JavaConstant.forInt(1)};\nvmAccess.asArrayConstant(intType, elems);","handlingStrategy":"validation","validationCode":"for (int i = 0; i < elements.length; i++) {\n    if (elements[i].getJavaKind() != expectedKind) {\n        throw new IllegalArgumentException(\"bad kind at \" + i);\n    }\n}","typeGuard":"static boolean kindsMatch(JavaConstant[] elems, JavaKind kind) {\n    for (JavaConstant c : elems) {\n        if (c.getJavaKind() != kind) return false;\n    }\n    return true;\n}","tryCatchPattern":"catch (IllegalArgumentException e) parsing the index/kind from the message is brittle; pre-validate instead and let the exception surface as a bug indicator.","preventionTips":["Use the typed JavaConstant.forX factory matching the component kind.","Centralize element construction in one helper per kind.","Remember: dimensions > 1 primitive arrays take object (nested-array) constants, not primitive ones."],"tags":["jvmci","espresso","graalvm","arrays","primitives","type-mismatch"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}