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
- Use binary properties without '=value': \p{Alphabetic} instead of \p{Alphabetic=Yes}.
- For enumerated values keep only the supported left-hand names: blk=, gc=, sc=, scx= (e.g. \p{sc=Greek}, \p{gc=Lu}).
- 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
- Use binary properties without '=value' and keep '=' forms to blk/gc/sc/scx only.
- Normalize patterns from PCRE/ICU sources before compiling on TRegex.
- Add pattern linting in CI for \p{...=...} syntax when patterns cross engines.
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
- Unsupported Unicode character property escape
- Unsupported Unicode character property '%s'
- Unsupported Unicode %s '%s'
- got illegal regionFrom value: %d. regionFrom must be >= 0 an
- got illegal regionTo value: %d. regionTo must be >= regionFr
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/071b0c7f6d04c39c.
Report an issue: GitHub.