oracle/graal · error · UnsupportedOperationException

got non-equal toIndex (%d) and regionTo (%d), support for th

Error message

got non-equal toIndex (%d) and regionTo (%d), support for this is not implemented yet

What it means

The 5-argument form of RegexExecNode currently only implements toIndex == regionTo. Passing a toIndex different from regionTo (even if otherwise in range) throws UnsupportedOperationException, signaling an engine limitation rather than invalid arguments.

Source

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

                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));
            }
        }
        return execute(frame, input, adjustFromIndex(input, (int) fromIndex, regionFrom, regionTo), toIndex, regionFrom, regionTo);
    }

    private int adjustFromIndex(TruffleString input, int fromIndex, int regionFrom, int regionTo) {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Pass toIndex equal to regionTo and enforce any tighter search end by shrinking regionTo.
  2. If you truly need an independent search window, fall back to host java.util.regex for that call.
  3. Track the TRegex repository for the 'non-equal toIndex/regionTo' support landing before exposing such an API.

Example fix

// before
exec(input, from, searchEnd, regionFrom, regionEnd); // searchEnd != regionEnd -> UnsupportedOperationException

// after
exec(input, from, regionEnd, regionFrom, regionEnd); // use regionEnd as toIndex; narrow regionFrom..searchEnd if needed
Defensive patterns

Strategy: fallback

Validate before calling

static boolean engineSupportsSearchWindow(long toIndex, long regionTo) {
    return toIndex == regionTo; // TRegex 5-arg exec only implements toIndex == regionTo
}

Try / catch

if (toIndex != regionTo) {
    // engine limitation: fall back to host java.util.regex for this call
    return hostRegexSearch(input, fromIndex, toIndex, regionFrom, regionTo);
}
return exec(input, fromIndex, regionTo, regionFrom, regionTo);

Prevention

When it happens

Trigger: Calling 5-arg exec where toIndexLong != regionToLong, e.g. trying to search only a prefix of the region (toIndex < regionTo) as Java's Matcher.region(from, to).find() with an additional end bound would.

Common situations: Porting code that assumes java.util.regex-style independent search-window and region bounds onto the Truffle regex engine; polyglot adapters exposing a richer region API than TRegex supports.

Related errors


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