oracle/graal · error · IllegalArgumentException
Value for {} cannot be empty
Error message
Value for {} cannot be empty What it means
PhaseFilterKey is the OptionKey for the graal phase filter option (e.g., -Dgraal.PhaseFilter). Its onValueUpdate hook (PhaseFilterKey.java:81) rejects an empty string because an empty filter matches nothing and is almost certainly a configuration mistake. The docs say to use "*" to match any phase.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/PhaseFilterKey.java:81
A phase name is matched as a substring.
For example:
PartialEscape:Loop=B.foo,A.*
matches PartialEscapePhase for compilation of all methods and any phase
containing "Loop" in its name for compilation of B.foo as well as all
methods in class A.
A phase filter specification cannot be empty. Specify "*" to match
any phase.""";
private final ConcurrentHashMap<String, BasePhase.PhaseFilter> parsedValues = new ConcurrentHashMap<>();
@Override
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, String oldValue, String newValue) {
if (newValue != null && newValue.isEmpty()) {
throw new IllegalArgumentException("Value for " + getName() + " cannot be empty");
}
}
/**
* Determines whether {@code phase} when applied to {@code graph} is matched by {@code filter}.
*/
public boolean matches(OptionValues options, BasePhase<?> phase, StructuredGraph graph) {
String filter = getValue(options);
if (filter == null) {
return false;
} else {
GraalError.guarantee(phase != null || phaselessGraphFilterToken != null, "Cannot pass null phase unless phaselessGraphFilterToken is non-null");
return parsedValues.computeIfAbsent(filter, f -> PhaseFilterKey.parse(f, phaselessGraphFilterToken)).matches(phase, graph);
}
}
/**
* Creates a phase filter based on a specification string. The string is a colon-separated listView on GitHub (pinned to a66e9ccd1d)
Solutions
- Remove the -Dgraal.<PhaseFilter>= flag entirely if no filtering is wanted
- Use "*" if the intent is to match all phases
- Fix the script/CI template so an unset variable omits the flag instead of emitting an empty value
Example fix
# before java -Dgraal.PrintFilters="$PHASE_FILTER" App # empty env var # after PHASE_FILTER="*" java -Dgraal.PrintFilters="$PHASE_FILTER" App
Defensive patterns
Strategy: validation
Validate before calling
String filter = System.getenv().getOrDefault("PHASE_FILTER", "*");
assert !filter.isEmpty() : "phase filter must not be empty; use '*'";
// then: -Dgraal.<PhaseFilterOption>=" + filter Prevention
- Default templated option values to '*' or omit the flag, never to empty string
- Smoke-test launcher scripts with all env vars unset
When it happens
Trigger: Setting the option to an empty value, e.g., -Dgraal.PhaseFilter="" or programmatically new OptionValues(..., PhaseFilterKey, "") — the IllegalArgumentException is thrown at option-update time.
Common situations: Scripts that build the option string from an unset environment variable, producing -Dgraal.PhaseFilter=; CI configs that template the flag with an empty default.
Related errors
- expected phase_name=filter pair in: {}
- Invalid directed inlining rules file path: {path}
- Invalid option
- "%s" is not a valid option for %s. Valid values are %s
- "%s" is not a valid option for %s. Valid values are %s
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/229bfa12e868b06b.
Report an issue: GitHub.