oracle/graal · error · IllegalArgumentException

Invalid VM option specified.

Error message

Invalid VM option %s specified. %s

What it means

Thrown by EspressoExternalVMAccessBuilder after an option key was recognized: the raw string value failed descriptor.getKey().getType().convert(value). Each option has a typed key (boolean, enum, int, string...), so a syntactically valid key with a wrong-typed value is rejected with IllegalArgumentException including the convert error.

Solutions

  1. Read the option's declared type from its OptionDescriptor and supply the value in the exact expected syntax (booleans are 'true'/'false', enums use the exact constant name, numbers in plain decimal)
  2. Strip surrounding quotes/whitespace that shells or properties loaders may have left in the value
  3. Validate candidate values with the same convert() call in a pre-flight loop so all bad values are reported before the engine starts

Example fix

// before
builder.option("engine.WarnInterpreterOnly", "no"); // not a boolean literal

// after
builder.option("engine.WarnInterpreterOnly", "false");
Defensive patterns

Strategy: validation

Validate before calling

OptionDescriptor d = findOptionDescriptor(group, key);
d.getKey().getType().convert(value); // pre-flight: throws the same convert error early with your context

Try / catch

catch (IllegalArgumentException e) { include key, value, and the option's declared type in the error report }

Prevention

When it happens

Trigger: Passing e.g. 'engine.Compilation=false' style mistakes like a non-numeric value to a numeric option, an unknown enum constant to an enum option, or 'yes'/'1' to a strictly boolean option expecting 'true'/'false'.

Common situations: Assuming loose truthy parsing ('yes', 'on', '1') for boolean options; passing arbitrary strings to enum-typed Espresso options; locale-specific number formats; values quoted incorrectly when options come from a properties file or shell.

Related errors


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

Appendix: source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccessBuilder.java:224

                } catch (IOException e) {
                    throw new IllegalArgumentException("Cannot use the specified log.file", e);
                }
                builder.logHandler(out);
                return;
            }
        }
        OptionDescriptor descriptor = findOptionDescriptor(group, key);
        if (descriptor == null) {
            key = JAVA_LANGUAGE_ID + "." + key;
            descriptor = findOptionDescriptor(JAVA_LANGUAGE_ID, key);
            if (descriptor == null) {
                throw new IllegalArgumentException("Unrecognized VM option: '" + vmOption);
            }
        }
        try {
            descriptor.getKey().getType().convert(value);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException(String.format("Invalid VM option %s specified. %s", vmOption, e.getMessage()));
        }
        builder.option(key, value);
    }

    private static OptionDescriptor findOptionDescriptor(String group, String key) {
        OptionDescriptors descriptors = null;
        switch (group) {
            case "engine":
            case "compiler":
                descriptors = getTempEngine().getOptions();
                break;
            default:
                Engine engine = getTempEngine();
                if (engine.getLanguages().containsKey(group)) {
                    descriptors = engine.getLanguages().get(group).getOptions();
                } else if (engine.getInstruments().containsKey(group)) {
                    descriptors = engine.getInstruments().get(group).getOptions();
                }

View on GitHub (pinned to a66e9ccd1d)