oracle/graal · error · IllegalArgumentException
Invalid VM option %s specified. %s
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.
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)
Solutions
- 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)
- Strip surrounding quotes/whitespace that shells or properties loaders may have left in the value
- 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
- Type your own config layer (boolean/enum/int fields) so values are rendered in the exact option syntax
- Never pass raw shell/properties values through untrimmed
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
- ConversionHandler does not implement the polyglot type conve
- Invalid log level %s specified. %s'
- Unrecognized VM option: '
- --java.SpecCompliance: Mode can be 'strict' or 'hotspot'.
- -Xverify: Mode can be 'none', 'remote' or 'all'.
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/a944c3f6881ff742.
Report an issue: GitHub.