{"record":{"id":"0c6a9ec9d925a28b","repo":"oracle/graal","slug":"expected-a-primitive-array-constant-got-0c6a9e","errorCode":null,"errorMessage":"Expected a primitive array constant, got {}","messagePattern":"Expected a primitive array constant, got (.+?)","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":597,"sourceCode":"    public JavaConstant createPrimitiveArray(JavaKind kind, int length) {\n        if (kind == null || !kind.isPrimitive() || kind == JavaKind.Void) {\n            throw new IllegalArgumentException(\"Expected a non-void primitive kind, got \" + kind);\n        }\n        if (length < 0) {\n            throw new NegativeArraySizeException(\"Negative array size: \" + length);\n        }\n        Value array = invokeJVMCIHelper(\"newPrimitiveArray\", (int) kind.getTypeChar(), 1, length);\n        return new EspressoExternalObjectConstant(this, array);\n    }\n\n    @Override\n    public JavaConstant clonePrimitiveArray(JavaConstant primitiveArray) {\n        if (!(primitiveArray instanceof EspressoExternalObjectConstant objectConstant)) {\n            throw new IllegalArgumentException(\"Expected an EspressoExternalObjectConstant, got \" + safeGetClass(primitiveArray));\n        }\n        EspressoResolvedObjectType arrayType = objectConstant.getType();\n        if (!(arrayType.isArray() && arrayType.getComponentType().isPrimitive())) {\n            throw new IllegalArgumentException(\"Expected a primitive array constant, got \" + arrayType);\n        }\n        Value copy = invokeJVMCIHelper(\"clonePrimitiveArray\", objectConstant.getValue());\n        return new EspressoExternalObjectConstant(this, copy);\n    }\n\n    @Override\n    public void copyArray(JavaConstant src, int srcPos, JavaConstant dest, int destPos, int length) {\n        if (!(src instanceof EspressoExternalObjectConstant srcArray)) {\n            throw new IllegalArgumentException(\"Expected an EspressoExternalObjectConstant for src, got \" + safeGetClass(src));\n        }\n        if (!(dest instanceof EspressoExternalObjectConstant destArray)) {\n            throw new IllegalArgumentException(\"Expected an EspressoExternalObjectConstant for dest, got \" + safeGetClass(dest));\n        }\n        if (!srcArray.getType().isArray()) {\n            throw new IllegalArgumentException(\"Expected an array constant for src, got \" + srcArray.getType());\n        }\n        if (!destArray.getType().isArray()) {\n            throw new IllegalArgumentException(\"Expected an array constant for dest, got \" + destArray.getType());","sourceCodeStart":579,"sourceCodeEnd":615,"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#L579-L615","documentation":"After unwrapping the constant, clonePrimitiveArray verifies the guest type is actually an array with a primitive component (e.g. byte[], int[]). Object arrays and non-array constants are rejected with IllegalArgumentException naming the discovered type, because the guest helper only clones primitive arrays.","triggerScenarios":"Passing an Espresso object-array constant (String[], Object[]) or a non-array object constant to clonePrimitiveArray.","commonSituations":"Generic snapshot helpers that assume all arrays are primitive; refactors changing an array's component type from primitive to boxed; passing the array's element instead of the array itself.","solutions":["Check the type first: arrayType.isArray() && arrayType.getComponentType().isPrimitive() (on the constant's Espresso type).","Use asArrayConstant/copyArray for object arrays instead of clonePrimitiveArray.","Log the constant's type when the guard fails to find where the wrong array originates."],"exampleFix":"// before\nJavaConstant copy = vmAccess.clonePrimitiveArray(arr);\n\n// after\nEspressoResolvedObjectType t = ((EspressoExternalObjectConstant) arr).getType();\nJavaConstant copy = (t.isArray() && t.getComponentType().isPrimitive())\n        ? vmAccess.clonePrimitiveArray(arr)\n        : vmAccess.copyArray(arr, 0, vmAccess.createPrimitiveArray(...), 0, len);","handlingStrategy":"validation","validationCode":"EspressoResolvedObjectType t = ((EspressoExternalObjectConstant) arr).getType();\nif (!(t.isArray() && t.getComponentType().isPrimitive())) {\n    // object array or non-array: use copyArray/asArrayConstant path\n}","typeGuard":"static boolean isGuestPrimitiveArray(JavaConstant c) {\n    if (!(c instanceof EspressoExternalObjectConstant e)) return false;\n    EspressoResolvedObjectType t = e.getType();\n    return t.isArray() && t.getComponentType().isPrimitive();\n}","tryCatchPattern":"catch (IllegalArgumentException e) with 'Expected a primitive array constant' -> log the reported type and reroute to the object-array copy path.","preventionTips":["Branch on component type before choosing clone vs copy.","Component-type refactors (primitive -> boxed) must update clone call sites.","Pass the array, not its element."],"tags":["jvmci","espresso","graalvm","arrays","type-mismatch"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}