oracle/graal · error · IllegalArgumentException
Could not unwrap an array constant: {}
Error message
Could not unwrap an array constant: {} What it means
copyMemory requires the source constant to be unwrappable to a live host array via snippetReflection.asObject(Object.class, src). The type check passed (it is a primitive array type), but asObject returned null, meaning the constant is not a materialized host object — e.g. null, a placeholder, or a constant created by a different reflection provider.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:490
private ResolvedJavaType lookupType(String name, ClassLoader loader) {
try {
Class<?> cls = Class.forName(name, false, loader);
return providers.getMetaAccess().lookupJavaType(cls);
} catch (ClassNotFoundException e) {
return null;
}
}
@Override
public void copyMemory(JavaConstant src, int srcFrom, int srcTo, byte[] dst, int dstFrom) {
ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(src);
if (arrayType == null || !arrayType.isArray() || !arrayType.getComponentType().isPrimitive()) {
throw new IllegalArgumentException("Expected a primitive array constant, got " + src);
}
var array = providers.getSnippetReflection().asObject(Object.class, src);
if (array == null) {
throw new IllegalArgumentException("Could not unwrap an array constant: " + src);
}
int sourceArrayEnd = Array.getLength(array) * arrayType.getComponentType().getJavaKind().getByteCount();
if (srcFrom < 0 || srcTo > sourceArrayEnd || srcTo < srcFrom) {
throw new IllegalArgumentException(
"Invalid input range: " + srcFrom + ".." + srcTo + " for array of length " + Array.getLength(array) + " with kind " + arrayType.getComponentType().getJavaKind());
}
int bytesToCopy = srcTo - srcFrom;
if (dstFrom < 0 || dstFrom > dst.length - bytesToCopy) {
throw new IllegalArgumentException("Invalid output range: " + dstFrom + ".." + (dstFrom + bytesToCopy) + " for array of length " + dst.length);
}
var unsafe = Unsafe.getUnsafe();
unsafe.copyMemory(array, unsafe.arrayBaseOffset(array.getClass()) + srcFrom, dst, Unsafe.ARRAY_BYTE_BASE_OFFSET + dstFrom, bytesToCopy);
}
/**
* Host mode performs the unaligned read with {@link Unsafe} against the unwrapped hosted array
* object.
*/View on GitHub (pinned to a66e9ccd1d)
Solutions
- Pre-check with providers.getSnippetReflection().asObject(Object.class, srcConst) and require non-null before copying
- Rebuild the constant from the live array via snippetReflection.forObject on the same runtime
- Reject non-materializable constants upstream instead of relying on copyMemory's guard
Example fix
// before
vmAccess.copyMemory(srcConst, 0, len, dst, 0);
// after
Object liveArray = providers.getSnippetReflection().asObject(Object.class, srcConst);
if (liveArray == null) {
throw new IllegalStateException("src constant has no live host object");
}
vmAccess.copyMemory(srcConst, 0, len, dst, 0); Defensive patterns
Strategy: validation
Validate before calling
if (providers.getSnippetReflection().asObject(Object.class, srcConst) == null) {
throw new IllegalStateException("copyMemory source not materializable: " + srcConst);
} Prevention
- Keep constants and the VMAccess on the same runtime lifecycle
- Rebuild constants from live arrays after any serialization boundary
- Fail fast on non-materializable constants in generic byte-dump utilities
When it happens
Trigger: Calling copyMemory with a constant that types as int[]/long[] etc. but cannot be materialized: NULL_POINTER, constants from another Graal runtime or guest VM, or synthesized constants with no backing object.
Common situations: AOT/image-build constants leaking into host-mode APIs; cross-VMAccess constant reuse; tests with hand-built constants.
Related errors
- Could not unwrap array: {}
- No original class for type {}
- Invalid input range: {}..{} for array of length {} with kind
- Invalid output range: {}..{} for array of length {}
- Expected an espresso constant got a {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/8c615c6d1bc70fb2.
Report an issue: GitHub.