{"record":{"id":"479be3e2090ac29f","repo":"oracle/graal","slug":"invalid-input-range-for-array-of-length","errorCode":null,"errorMessage":"Invalid input range: {}..{} for array of length {} with kind {}","messagePattern":"Invalid input range: (.+?)\\.\\.(.+?) for array of length (.+?) with kind (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":494,"sourceCode":"            return providers.getMetaAccess().lookupJavaType(cls);\n        } catch (ClassNotFoundException e) {\n            return null;\n        }\n    }\n\n    @Override\n    public void copyMemory(JavaConstant src, int srcFrom, int srcTo, byte[] dst, int dstFrom) {\n        ResolvedJavaType arrayType = getProviders().getMetaAccess().lookupJavaType(src);\n        if (arrayType == null || !arrayType.isArray() || !arrayType.getComponentType().isPrimitive()) {\n            throw new IllegalArgumentException(\"Expected a primitive array constant, got \" + src);\n        }\n        var array = providers.getSnippetReflection().asObject(Object.class, src);\n        if (array == null) {\n            throw new IllegalArgumentException(\"Could not unwrap an array constant: \" + src);\n        }\n        int sourceArrayEnd = Array.getLength(array) * arrayType.getComponentType().getJavaKind().getByteCount();\n        if (srcFrom < 0 || srcTo > sourceArrayEnd || srcTo < srcFrom) {\n            throw new IllegalArgumentException(\n                            \"Invalid input range: \" + srcFrom + \"..\" + srcTo + \" for array of length \" + Array.getLength(array) + \" with kind \" + arrayType.getComponentType().getJavaKind());\n        }\n        int bytesToCopy = srcTo - srcFrom;\n        if (dstFrom < 0 || dstFrom > dst.length - bytesToCopy) {\n            throw new IllegalArgumentException(\"Invalid output range: \" + dstFrom + \"..\" + (dstFrom + bytesToCopy) + \" for array of length \" + dst.length);\n        }\n        var unsafe = Unsafe.getUnsafe();\n        unsafe.copyMemory(array, unsafe.arrayBaseOffset(array.getClass()) + srcFrom, dst, Unsafe.ARRAY_BYTE_BASE_OFFSET + dstFrom, bytesToCopy);\n    }\n\n    /**\n     * Host mode performs the unaligned read with {@link Unsafe} against the unwrapped hosted array\n     * object.\n     */\n    @Override\n    public JavaConstant readPrimitiveArrayUnaligned(JavaConstant primitiveArray, JavaKind kind, int offset) {\n        if (kind == null || !kind.isPrimitive() || kind == JavaKind.Void) {\n            throw new IllegalArgumentException(\"Expected a non-void primitive kind, got \" + kind);","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L476-L512","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nint n = Array.getLength(arr); // element count, wrong for long[]\nvmAccess.copyMemory(srcConst, 0, n, dst, 0);\n\n// after\nJavaKind k = providers.getMetaAccess().lookupJavaType(srcConst).getComponentType().getJavaKind();\nint byteLen = Array.getLength(arr) * k.getByteCount();\nvmAccess.copyMemory(srcConst, 0, byteLen, dst, 0);","handlingStrategy":"validation","validationCode":"JavaKind k = providers.getMetaAccess().lookupJavaType(src).getComponentType().getJavaKind();\nint byteLen = Array.getLength(liveArray) * k.getByteCount();\nif (srcFrom < 0 || srcTo < srcFrom || srcTo > byteLen) {\n    throw new IndexOutOfBoundsException(\"src range \" + srcFrom + \"..\" + srcTo + \" outside 0..\" + byteLen);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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[]"],"tags":["graalvm","vmaccess","copymemory","bounds","off-by-one"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}