oracle/graal · error · IllegalArgumentException

got illegal toIndex value: %d. toIndex must be >= fromIndex

Error message

got illegal toIndex value: %d. toIndex must be >= fromIndex (%d) and <= regionTo (%d)

What it means

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.

Source

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

            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 {
            assert args.length == 2;
            toIndex = length;
            regionFrom = 0;
            regionTo = length;
            if (fromIndex < 0 || fromIndex > length) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalArgumentException(String.format("got illegal fromIndex value: %d. fromIndex must be >= 0 and <= input length (%d)", fromIndex, length));
            }
        }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Default toIndex to regionTo (the only supported value today) instead of input.length().
  2. Clamp: toIndex = Math.max(fromIndex, Math.min(toIndex, regionTo)).
  3. Verify the argument order of the 5-arg exec call against the engine's signature.

Example fix

// before
exec(input, from, input.length(), regionFrom, regionTo); // toIndex > regionTo

// after
exec(input, from, regionTo, regionFrom, regionTo);
Defensive patterns

Strategy: validation

Validate before calling

static boolean validToIndex(long toIndex, long fromIndex, long regionTo) {
    return toIndex >= fromIndex && toIndex <= regionTo;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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