oracle/graal · error · IllegalArgumentException

Binary property %s cannot appear to the left of '=' in a Uni

Error message

Binary property %s cannot appear to the left of '=' in a Unicode property escape

What it means

UnicodeProperties.normalizePropertySpec accepts the form 'name=value' only for enumerated properties where name is blk (block), gc (general category), sc/scx (script / script extensions). A binary (boolean) property name on the left of '=', such as \p{Alphabetic=Yes}, has no defined value space, so it throws IllegalArgumentException.

Source

Thrown at regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/charset/UnicodeProperties.java:176

    private String normalizePropertySpec(String propertySpec) {
        int equals = propertySpec.indexOf('=');
        if (equals >= 0) {
            String propertyName = normalizePropertyName(propertySpec.substring(0, equals));
            String propertyValue = propertySpec.substring(equals + 1);
            switch (propertyName) {
                case "blk":
                    propertyValue = normalizeBlockName(propertyValue);
                    break;
                case "gc":
                    propertyValue = normalizeGeneralCategoryName(propertyValue);
                    break;
                case "sc":
                case "scx":
                    propertyValue = normalizeScriptName(propertyValue);
                    break;
                default:
                    CompilerDirectives.transferToInterpreterAndInvalidate();
                    throw new IllegalArgumentException(String.format("Binary property %s cannot appear to the left of '=' in a Unicode property escape", propertySpec.substring(0, equals)));
            }
            return propertyName + "=" + propertyValue;
        } else if (isSupportedGeneralCategory(propertySpec)) {
            return "gc=" + normalizeGeneralCategoryName(propertySpec);
        } else {
            return normalizePropertyName(propertySpec);
        }
    }

    private String normalizePropertyName(String propertyName) {
        String name = returnOrThrow(propertyName, "character property", data.lookupPropertyAlias(propertyName, nameMatchingMode));
        if (!withOtherProperties() && OTHER_PROPERTIES_NAMES_SET.contains(name)) {
            throw new IllegalArgumentException(String.format("Unsupported Unicode character property '%s'", propertyName));
        }
        return name;
    }

    private String normalizeGeneralCategoryName(String generalCategoryName) {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Use binary properties without '=value': \p{Alphabetic} instead of \p{Alphabetic=Yes}.
  2. For enumerated values keep only the supported left-hand names: blk=, gc=, sc=, scx= (e.g. \p{sc=Greek}, \p{gc=Lu}).
  3. If you generate patterns programmatically, normalize property syntax to these forms before compilation.

Example fix

// before
String p = "\\p{Alphabetic=Yes}+"; // binary property with '=' -> throws

// after
String p = "\\p{Alphabetic}+"; // or enumerated form: "\\p{gc=L}+"
Defensive patterns

Strategy: validation

Validate before calling

import java.util.Set;
private static final Set<String> ENUMERATED_LEFT_HAND = Set.of("blk", "gc", "sc", "scx");

static String normalizeEscape(String spec) {
    int eq = spec.indexOf('=');
    if (eq < 0) return spec; // binary property form is fine
    String lhs = spec.substring(0, eq);
    if (!ENUMERATED_LEFT_HAND.contains(lhs)) {
        return lhs; // drop '=value' -> use the binary form \p{lhs}
    }
    return spec;
}

Prevention

When it happens

Trigger: Writing \p{BinaryName=...} in a pattern, e.g. \p{Alpha=true}, \p{Uppercase=Yes}, or any \p{X=Y} where X is not blk/gc/sc/scx after alias lookup.

Common situations: Patterns ported from PCRE/ICU/.NET, which accept forms like \p{Alpha=Y} or \p{Alphabetic: Yes}; users assuming java.util.regex-style boolean syntax generalizes to '=' forms.

Related errors


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