oracle/graal · error · IllegalArgumentException
Invalid input range: {}..{} for array of length {} with kind
Error message
Invalid input range: {}..{} for array of length {} with kind {} What it means
copyMemory treats srcFrom/srcTo as byte offsets into the primitive array's raw storage (element size = component JavaKind byte count). This IllegalArgumentException reports that the requested byte range is invalid: srcFrom negative, srcTo beyond the array's total byte length, or srcTo < srcFrom.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:494
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.
*/
@Override
public JavaConstant readPrimitiveArrayUnaligned(JavaConstant primitiveArray, JavaKind kind, int offset) {
if (kind == null || !kind.isPrimitive() || kind == JavaKind.Void) {
throw new IllegalArgumentException("Expected a non-void primitive kind, got " + kind);View on GitHub (pinned to a66e9ccd1d)
Solutions
- Compute byte bounds explicitly: byteLen = arrayLength * componentKind.getByteCount(); use 0 <= srcFrom <= srcTo <= byteLen
- If you want whole-array copy, pass 0 and providers-computed byteLen rather than element length
- Add a range-check helper so all copyMemory call sites share the same arithmetic
Example fix
// before int n = Array.getLength(arr); // element count, wrong for long[] vmAccess.copyMemory(srcConst, 0, n, dst, 0); // after JavaKind k = providers.getMetaAccess().lookupJavaType(srcConst).getComponentType().getJavaKind(); int byteLen = Array.getLength(arr) * k.getByteCount(); vmAccess.copyMemory(srcConst, 0, byteLen, dst, 0);
Defensive patterns
Strategy: validation
Validate before calling
JavaKind k = providers.getMetaAccess().lookupJavaType(src).getComponentType().getJavaKind();
int byteLen = Array.getLength(liveArray) * k.getByteCount();
if (srcFrom < 0 || srcTo < srcFrom || srcTo > byteLen) {
throw new IndexOutOfBoundsException("src range " + srcFrom + ".." + srcTo + " outside 0.." + byteLen);
} Prevention
- Always multiply element counts by getByteCount() before passing ranges
- Name variables byteFrom/byteTo to make units explicit
- Property-test range math against java.util.Arrays copyOfRange for byte[]
When it happens
Trigger: Calling copyMemory(src, srcFrom, srcTo, dst, dstFrom) where srcFrom < 0, or srcFrom > srcTo, or srcTo > Array.getLength(array) * componentKind.getByteCount(). Classic case: computing srcTo in elements (e.g. 4 for an int[4]) while the API expects bytes (16), or forgetting long arrays have 8-byte elements.
Common situations: Unit confusion between element count and byte count, especially for long[]/double[] where byte length is 8x element length; porting code that used element indices; off-by-one at the end boundary.
Related errors
- Invalid output range: {}..{} for array of length {}
- Could not unwrap an array constant: {}
- Element {} should be a {}, got {}
- Element {} should be an object, got {}
- Expected an array constant, got {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/479be3e2090ac29f.
Report an issue: GitHub.