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 list

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Remove the -Dgraal.<PhaseFilter>= flag entirely if no filtering is wanted
  2. Use "*" if the intent is to match all phases
  3. 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

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


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