{"record":{"id":"f6a2b61c5fdfacf3","repo":"oracle/graal","slug":"got-illegal-toindex-value-d-toindex-must-be","errorCode":null,"errorMessage":"got illegal toIndex value: %d. toIndex must be >= fromIndex (%d) and <= regionTo (%d)","messagePattern":"got illegal toIndex value: (.+?)\\. toIndex must be >= fromIndex \\((.+?)\\) and <= regionTo \\((.+?)\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/RegexExecNode.java","lineNumber":98,"sourceCode":"            long toIndexLong = toLongNode.execute(args[2]);\n            long regionFromLong = toLongNode.execute(args[3]);\n            long regionToLong = toLongNode.execute(args[4]);\n            if (regionFromLong < 0 || regionFromLong > length) {\n                CompilerDirectives.transferToInterpreterAndInvalidate();\n                throw new IllegalArgumentException(String.format(\"got illegal regionFrom value: %d. regionFrom must be >= 0 and <= input length (%d)\", regionFromLong, length));\n            }\n            if (regionToLong < regionFromLong || regionToLong > length) {\n                CompilerDirectives.transferToInterpreterAndInvalidate();\n                throw new IllegalArgumentException(String.format(\"got illegal regionTo value: %d. regionTo must be >= regionFrom (%d) and <= input length (%d)\", regionToLong, regionFromLong, length));\n            }\n            if (fromIndex < regionFromLong || fromIndex > regionToLong) {\n                CompilerDirectives.transferToInterpreterAndInvalidate();\n                throw new IllegalArgumentException(\n                                String.format(\"got illegal fromIndex value: %d. fromIndex must be >= regionFrom (%d) and <= regionTo (%d)\", fromIndex, regionFromLong, regionToLong));\n            }\n            if (toIndexLong < fromIndex || toIndexLong > regionToLong) {\n                CompilerDirectives.transferToInterpreterAndInvalidate();\n                throw new IllegalArgumentException(String.format(\"got illegal toIndex value: %d. toIndex must be >= fromIndex (%d) and <= regionTo (%d)\", toIndexLong, fromIndex, regionToLong));\n            }\n            if (toIndexLong != regionToLong) {\n                CompilerDirectives.transferToInterpreterAndInvalidate();\n                throw new UnsupportedOperationException(String.format(\"got non-equal toIndex (%d) and regionTo (%d), support for this is not implemented yet\", toIndexLong, regionToLong));\n            }\n            toIndex = (int) toIndexLong;\n            regionFrom = (int) regionFromLong;\n            regionTo = (int) regionToLong;\n        } else {\n            assert args.length == 2;\n            toIndex = length;\n            regionFrom = 0;\n            regionTo = length;\n            if (fromIndex < 0 || fromIndex > length) {\n                CompilerDirectives.transferToInterpreterAndInvalidate();\n                throw new IllegalArgumentException(String.format(\"got illegal fromIndex value: %d. fromIndex must be >= 0 and <= input length (%d)\", fromIndex, length));\n            }\n        }","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/RegexExecNode.java#L80-L116","documentation":"In RegexExecNode's 5-argument form, toIndex must satisfy fromIndex <= toIndex <= regionTo. A toIndex before the start index or beyond the region end throws IllegalArgumentException.","triggerScenarios":"Calling 5-arg exec with toIndex < fromIndex or toIndex > regionTo, e.g. fromIndex=8, toIndex=3, or toIndex equal to the full input length while regionTo is smaller.","commonSituations":"Adapters defaulting toIndex to input.length() even when a region shorter than the string was requested; passing the region bounds and search window in the wrong order.","solutions":["Default toIndex to regionTo (the only supported value today) instead of input.length().","Clamp: toIndex = Math.max(fromIndex, Math.min(toIndex, regionTo)).","Verify the argument order of the 5-arg exec call against the engine's signature."],"exampleFix":"// before\nexec(input, from, input.length(), regionFrom, regionTo); // toIndex > regionTo\n\n// after\nexec(input, from, regionTo, regionFrom, regionTo);","handlingStrategy":"validation","validationCode":"static boolean validToIndex(long toIndex, long fromIndex, long regionTo) {\n    return toIndex >= fromIndex && toIndex <= regionTo;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default toIndex to regionTo rather than input.length() when a region is set.","Keep the 5-arg argument order (from, to, regionFrom, regionTo) in adapter unit tests.","Clamp toIndex to the region before calling the engine."],"tags":["regex","truffle","graalvm","argument-validation","region"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}