oracle/graal · error · IllegalArgumentException
Element {} should be an object, got {}
Error message
Element {} should be an object, got {} What it means
Thrown by HostVMAccess.writeArrayElement when the target array has a reference (object) component type but the JavaConstant element is not an object kind. The object branch unboxes the element via snippetReflection.asObject(Object.class, element), which only works for object constants; primitive constants such as JavaKind.Int or JavaKind.Long cannot be stored into an Object[]/String[] slot.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:350
throw new IllegalArgumentException("Expected an array constant for src, got " + src);
}
Object destArray = providers.getSnippetReflection().asObject(Object.class, dest);
if (destArray == null || !destArray.getClass().isArray()) {
throw new IllegalArgumentException("Expected an array constant for dest, got " + dest);
}
System.arraycopy(srcArray, srcPos, destArray, destPos, length);
}
private void doWriteArrayElement(Object array, ResolvedJavaType componentType, int index, JavaConstant element) {
Object unwrappedValue;
if (componentType.isPrimitive()) {
if (componentType.getJavaKind() != element.getJavaKind()) {
throw new IllegalArgumentException("Element " + element + " should be a " + componentType.getJavaKind() + ", got " + element.getJavaKind());
}
unwrappedValue = element.asBoxedPrimitive();
} else {
if (!element.getJavaKind().isObject()) {
throw new IllegalArgumentException("Element " + element + " should be an object, got " + componentType);
}
unwrappedValue = providers.getSnippetReflection().asObject(Object.class, element);
}
Array.set(array, index, unwrappedValue);
}
@Override
public void writeArrayElement(JavaConstant array, int index, JavaConstant element) {
ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(array);
if (arrayType == null || !arrayType.isArray()) {
throw new IllegalArgumentException("Expected an array constant, got " + array);
}
Object asObject = providers.getSnippetReflection().asObject(Object.class, array);
if (asObject == null) {
throw new IllegalArgumentException("Could not unwrap array: " + array);
}
doWriteArrayElement(asObject, arrayType.getComponentType(), index, element);
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Wrap primitives before storing: for a boxable value use snippetReflection/forObject(Integer.valueOf(v)) instead of JavaConstant.forInt(v)
- Check element.getJavaKind().isObject() before the call and convert primitives to object constants for Object[] targets
- Fix the producer so reference-typed array slots only ever receive object constants
Example fix
// before vmAccess.writeArrayElement(objectArrayConst, 0, JavaConstant.forInt(7)); // after JavaConstant boxed = providers.getSnippetReflection().forObject(Integer.valueOf(7)); vmAccess.writeArrayElement(objectArrayConst, 0, boxed);
Defensive patterns
Strategy: type-guard
Validate before calling
ResolvedJavaType comp = providers.getMetaAccess().lookupJavaType(arrayConst).getComponentType();
if (!comp.isPrimitive() && !elementConst.getJavaKind().isObject()) {
throw new IllegalArgumentException("Primitive constant " + elementConst + " cannot go into reference array of " + comp);
} Type guard
boolean storableInRefArray(JavaConstant element) {
return element.getJavaKind().isObject();
} Prevention
- Box primitives with snippetReflection.forObject before storing into Object[]/interface arrays
- Keep a single conversion point where primitive values become object constants
- Log element kind and component type whenever a generic write path handles mixed arrays
When it happens
Trigger: Calling VMAccess.writeArrayElement with an array whose componentType.isPrimitive() is false (e.g. String[], Object[]) while passing a constant whose element.getJavaKind().isObject() is false — for example JavaConstant.forInt(1) or a primitive box handled as a primitive kind.
Common situations: Auto-boxing assumptions: code that stores a primitive constant into an Object[] expecting boxing; forwarding fields/constants from IR where the declared type is Object but the constant was materialized as a raw primitive kind.
Related errors
- Element {} should be a {}, got {}
- Expected an array constant, got {}
- Unexpected value: ${instance}
- Illegal argument type: arguments[{}] of type {} could not be
- Illegal argument type: receiver of type {} could not be conv
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/6e27cc11af08468b.
Report an issue: GitHub.