oracle/graal · error · IllegalArgumentException

got illegal regionTo value: %d. regionTo must be >= regionFr

Error message

got illegal regionTo value: %d. regionTo must be >= regionFrom (%d) and <= input length (%d)

What it means

In RegexExecNode's 5-argument form, regionTo must satisfy regionFrom <= regionTo <= inputLength. A regionTo smaller than regionFrom or beyond the end of the input throws IllegalArgumentException with this message.

Source

Thrown at regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/RegexExecNode.java:89

        int length = InputOps.length(input, getEncoding());
        long fromIndex = toLongNode.execute(args[1]);
        if (fromIndex > Integer.MAX_VALUE) {
            return RegexResult.getNoMatchInstance();
        }
        final int toIndex;
        final int regionFrom;
        final int regionTo;
        if (args.length == 5) {
            long toIndexLong = toLongNode.execute(args[2]);
            long regionFromLong = toLongNode.execute(args[3]);
            long regionToLong = toLongNode.execute(args[4]);
            if (regionFromLong < 0 || regionFromLong > length) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalArgumentException(String.format("got illegal regionFrom value: %d. regionFrom must be >= 0 and <= input length (%d)", regionFromLong, length));
            }
            if (regionToLong < regionFromLong || regionToLong > length) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalArgumentException(String.format("got illegal regionTo value: %d. regionTo must be >= regionFrom (%d) and <= input length (%d)", regionToLong, regionFromLong, length));
            }
            if (fromIndex < regionFromLong || fromIndex > regionToLong) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalArgumentException(
                                String.format("got illegal fromIndex value: %d. fromIndex must be >= regionFrom (%d) and <= regionTo (%d)", fromIndex, regionFromLong, regionToLong));
            }
            if (toIndexLong < fromIndex || toIndexLong > regionToLong) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalArgumentException(String.format("got illegal toIndex value: %d. toIndex must be >= fromIndex (%d) and <= regionTo (%d)", toIndexLong, fromIndex, regionToLong));
            }
            if (toIndexLong != regionToLong) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new UnsupportedOperationException(String.format("got non-equal toIndex (%d) and regionTo (%d), support for this is not implemented yet", toIndexLong, regionToLong));
            }
            toIndex = (int) toIndexLong;
            regionFrom = (int) regionFromLong;
            regionTo = (int) regionToLong;
        } else {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Normalize arguments so regionTo = Math.max(regionFrom, Math.min(regionTo, inputLength)).
  2. Verify argument order at the call site (from before to) when bridging from another regex API.
  3. Recompute region bounds from the current input string rather than reusing stale ones.

Example fix

// before
exec(input, 0, len, from, to); // to < from when caller swaps bounds

// after
if (to < from) { int t = from; from = to; to = t; }
to = Math.min(to, input.length());
exec(input, 0, to, from, to);
Defensive patterns

Strategy: validation

Validate before calling

static boolean validRegionTo(long regionFrom, long regionTo, int inputLength) {
    return regionTo >= regionFrom && regionTo <= inputLength;
}

Prevention

When it happens

Trigger: Calling the 5-arg regex exec where the 5th argument is less than the 4th (regionTo < regionFrom) or greater than the input length, e.g. regionFrom=10, regionTo=5, or regionTo=input.length()+2.

Common situations: Guest-language adapters translating APIs like Java Matcher.region(from, to) with swapped or off-by-one arguments; code that copies region bounds from a previous match on a longer string; unterminated searches where regionTo defaults to -1.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/47012439138e2713. Report an issue: GitHub.