{"record":{"id":"3b31cf2d306fb8bd","repo":"oracle/graal","slug":"element-should-be-a-got","errorCode":null,"errorMessage":"Element {} should be a {}, got {}","messagePattern":"Element (.+?) should be a (.+?), got (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":345,"sourceCode":"\n    @Override\n    public void copyArray(JavaConstant src, int srcPos, JavaConstant dest, int destPos, int length) {\n        Object srcArray = providers.getSnippetReflection().asObject(Object.class, src);\n        if (srcArray == null || !srcArray.getClass().isArray()) {\n            throw new IllegalArgumentException(\"Expected an array constant for src, got \" + src);\n        }\n        Object destArray = providers.getSnippetReflection().asObject(Object.class, dest);\n        if (destArray == null || !destArray.getClass().isArray()) {\n            throw new IllegalArgumentException(\"Expected an array constant for dest, got \" + dest);\n        }\n        System.arraycopy(srcArray, srcPos, destArray, destPos, length);\n    }\n\n    private void doWriteArrayElement(Object array, ResolvedJavaType componentType, int index, JavaConstant element) {\n        Object unwrappedValue;\n        if (componentType.isPrimitive()) {\n            if (componentType.getJavaKind() != element.getJavaKind()) {\n                throw new IllegalArgumentException(\"Element \" + element + \" should be a \" + componentType.getJavaKind() + \", got \" + element.getJavaKind());\n            }\n            unwrappedValue = element.asBoxedPrimitive();\n        } else {\n            if (!element.getJavaKind().isObject()) {\n                throw new IllegalArgumentException(\"Element \" + element + \" should be an object, got \" + componentType);\n            }\n            unwrappedValue = providers.getSnippetReflection().asObject(Object.class, element);\n        }\n        Array.set(array, index, unwrappedValue);\n    }\n\n    @Override\n    public void writeArrayElement(JavaConstant array, int index, JavaConstant element) {\n        ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(array);\n        if (arrayType == null || !arrayType.isArray()) {\n            throw new IllegalArgumentException(\"Expected an array constant, got \" + array);\n        }\n        Object asObject = providers.getSnippetReflection().asObject(Object.class, array);","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L327-L363","documentation":"Thrown by HostVMAccess.writeArrayElement when the target array has a primitive component type but the JavaConstant element has a different JavaKind (e.g. writing a JavaKind.Int constant into an int[] is fine, but writing JavaKind.Long into int[] fails). The host-mode VMAccess implementation unwraps the element with asBoxedPrimitive(), which requires the kinds to match exactly. There is no implicit numeric conversion.","triggerScenarios":"Calling VMAccess.writeArrayElement(arrayConstant, index, element) where metaAccess.lookupJavaType(array).getComponentType().isPrimitive() is true but componentType.getJavaKind() != element.getJavaKind(). Example: writing JavaConstant.forInt(1) into a long[] constant, or a forDouble constant into a float[].","commonSituations":"Generically forwarding constants from parsed bytecode or a serializer that assumes the JVM widens/narrows primitives; building test fixtures where the array kind and the constant factory (forInt vs forLong vs forShort) get out of sync.","solutions":["Match the constant factory to the component kind: use JavaConstant.forInt/forLong/forDouble etc. according to arrayType.getComponentType().getJavaKind()","Before writing, branch on the component kind and convert the value (e.g. JavaConstant.forLong(element.asInt()) when storing into a long[])","If the value is genuinely dynamic, validate element.getJavaKind() == componentType.getJavaKind() and fail early with your own error message"],"exampleFix":"// before\nvmAccess.writeArrayElement(intArrayConst, 0, JavaConstant.forLong(42));\n\n// after\nJavaKind kind = metaAccess.lookupJavaType(intArrayConst).getComponentType().getJavaKind();\nJavaConstant element = switch (kind) {\n    case Int -> JavaConstant.forInt(42);\n    case Long -> JavaConstant.forLong(42);\n    default -> throw new IllegalStateException(\"Unhandled kind \" + kind);\n};\nvmAccess.writeArrayElement(intArrayConst, 0, element);","handlingStrategy":"type-guard","validationCode":"JavaKind component = providers.getMetaAccess().lookupJavaType(arrayConst).getComponentType().getJavaKind();\nif (component.isPrimitive() && elementConst.getJavaKind() != component) {\n    throw new IllegalArgumentException(\"Element kind \" + elementConst.getJavaKind() + \" != component kind \" + component);\n}","typeGuard":"boolean kindsMatch(JavaConstant array, JavaConstant element, MetaAccessProvider meta) {\n    ResolvedJavaType t = meta.lookupJavaType(array);\n    return t != null && t.isArray() && t.getComponentType().getJavaKind() == element.getJavaKind();\n}","tryCatchPattern":"catch (IllegalArgumentException e) when message starts with \"Element \" and contains \"should be a\": rethrow with caller context (array type + element constant).","preventionTips":["Always derive the JavaConstant factory from the component JavaKind, never hardcode it","Centralize array-element writes in one helper that kind-checks once","In tests, assert kind equality before writing to catch fixture drift"],"tags":["graalvm","vmaccess","array","type-mismatch","primitive"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}