oracle/graal · error · IllegalArgumentException
Expected a primitive array constant, got {}
Error message
Expected a primitive array constant, got {} What it means
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().
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:304
/**
* Host mode materializes the primitive array with reflection and then wraps it as a
* {@link JavaConstant} through {@link SnippetReflectionProvider#forObject(Object)}.
*/
@Override
public JavaConstant createPrimitiveArray(JavaKind kind, int length) {
if (kind == null || !kind.isPrimitive() || kind == JavaKind.Void) {
throw new IllegalArgumentException("Expected a non-void primitive kind, got " + kind);
}
Object array = Array.newInstance(kind.toJavaClass(), length);
return providers.getSnippetReflection().forObject(array);
}
@Override
public JavaConstant clonePrimitiveArray(JavaConstant primitiveArray) {
ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(primitiveArray);
if (arrayType == null || !arrayType.isArray() || !arrayType.getComponentType().isPrimitive()) {
throw new IllegalArgumentException("Expected a primitive array constant, got " + primitiveArray);
}
Object source = providers.getSnippetReflection().asObject(Object.class, primitiveArray);
if (source == null) {
throw new IllegalArgumentException("Could not unwrap a primitive array constant: " + primitiveArray);
}
/*
* Keep cloning explicit by primitive array kind. This avoids reflective clone access and
* preserves exact array runtime type through each typed clone() call.
*/
Object copy = switch (source) {
case boolean[] array -> array.clone();
case byte[] array -> array.clone();
case short[] array -> array.clone();
case char[] array -> array.clone();
case int[] array -> array.clone();
case long[] array -> array.clone();
case float[] array -> array.clone();
case double[] array -> array.clone();View on GitHub (pinned to a66e9ccd1d)
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
Example fix
// before
JavaConstant copy = hostVM.clonePrimitiveArray(objectArrayConstant); // throws
// after
ResolvedJavaType t = metaAccess.lookupJavaType(constant);
if (t != null && t.isArray() && t.getComponentType().isPrimitive()) {
JavaConstant copy = hostVM.clonePrimitiveArray(constant);
} Defensive patterns
Strategy: type-guard
Validate before calling
ResolvedJavaType t = metaAccess.lookupJavaType(constant); boolean ok = t != null && t.isArray() && t.getComponentType().isPrimitive();
Type guard
static boolean isPrimitiveArrayConstant(JavaConstant c, MetaAccessProvider m) {
ResolvedJavaType t = m.lookupJavaType(c);
return t != null && t.isArray() && t.getComponentType().isPrimitive();
} Try / catch
catch (IllegalArgumentException e) { route object arrays to their own clone path } Prevention
- Check component primitiveness before cloning
- Keep object-array and primitive-array copy paths separate
- Type constants with the meta access that produced them
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not obtain the original class for {}
- Expected a non-void primitive kind, got {}
- Could not unwrap a primitive array constant: {}
- Expected an array constant for src, got {}
- Expected an array constant for dest, got {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/b30d753c627543ca.
Report an issue: GitHub.