{"record":{"id":"b30d753c627543ca","repo":"oracle/graal","slug":"expected-a-primitive-array-constant-got","errorCode":null,"errorMessage":"Expected a primitive array constant, got {}","messagePattern":"Expected a primitive array constant, got (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":304,"sourceCode":"\n    /**\n     * Host mode materializes the primitive array with reflection and then wraps it as a\n     * {@link JavaConstant} through {@link SnippetReflectionProvider#forObject(Object)}.\n     */\n    @Override\n    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        Object array = Array.newInstance(kind.toJavaClass(), length);\n        return providers.getSnippetReflection().forObject(array);\n    }\n\n    @Override\n    public JavaConstant clonePrimitiveArray(JavaConstant primitiveArray) {\n        ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(primitiveArray);\n        if (arrayType == null || !arrayType.isArray() || !arrayType.getComponentType().isPrimitive()) {\n            throw new IllegalArgumentException(\"Expected a primitive array constant, got \" + primitiveArray);\n        }\n        Object source = providers.getSnippetReflection().asObject(Object.class, primitiveArray);\n        if (source == null) {\n            throw new IllegalArgumentException(\"Could not unwrap a primitive array constant: \" + primitiveArray);\n        }\n        /*\n         * Keep cloning explicit by primitive array kind. This avoids reflective clone access and\n         * preserves exact array runtime type through each typed clone() call.\n         */\n        Object copy = switch (source) {\n            case boolean[] array -> array.clone();\n            case byte[] array -> array.clone();\n            case short[] array -> array.clone();\n            case char[] array -> array.clone();\n            case int[] array -> array.clone();\n            case long[] array -> array.clone();\n            case float[] array -> array.clone();\n            case double[] array -> array.clone();","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L286-L322","documentation":"Thrown by HostVMAccess.clonePrimitiveArray when the argument constant does not denote a primitive array: its resolved type is null, not an array, or has a non-primitive component type. It is the entry guard before the constant is unwrapped and dispatched to a typed clone().","triggerScenarios":"Calling clonePrimitiveArray(constant) where metaAccess.lookupJavaType(primitiveArray) is null or the type fails isArray()/getComponentType().isPrimitive() — e.g. passing an Object[] constant, a boxed scalar constant, or a constant the meta access cannot type.","commonSituations":"Generic deep-copy helpers applied to any constant without checking the component kind; refactors where a primitive array is replaced by a boxed/wrapper array; constants coming from a different meta-access context that cannot be typed.","solutions":["Check the argument first: the constant must type-resolve to an array with primitive component (see the same condition in the guard)","Use the dedicated array clone paths for object arrays instead of clonePrimitiveArray","Ensure the constant was produced by forObject over a real primitive array (int[], double[], ...) in the same provider context"],"exampleFix":"// before\nJavaConstant copy = hostVM.clonePrimitiveArray(objectArrayConstant);  // throws\n\n// after\nResolvedJavaType t = metaAccess.lookupJavaType(constant);\nif (t != null && t.isArray() && t.getComponentType().isPrimitive()) {\n    JavaConstant copy = hostVM.clonePrimitiveArray(constant);\n}","handlingStrategy":"type-guard","validationCode":"ResolvedJavaType t = metaAccess.lookupJavaType(constant);\nboolean ok = t != null && t.isArray() && t.getComponentType().isPrimitive();","typeGuard":"static boolean isPrimitiveArrayConstant(JavaConstant c, MetaAccessProvider m) {\n    ResolvedJavaType t = m.lookupJavaType(c);\n    return t != null && t.isArray() && t.getComponentType().isPrimitive();\n}","tryCatchPattern":"catch (IllegalArgumentException e) { route object arrays to their own clone path }","preventionTips":["Check component primitiveness before cloning","Keep object-array and primitive-array copy paths separate","Type constants with the meta access that produced them"],"tags":["graalvm","hostvmaccess","arrays","type-guard"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}