oracle/graal · error · IllegalArgumentException
Unrecognized VM option: '
Error message
Unrecognized VM option: '
What it means
Thrown by EspressoExternalVMAccessBuilder when a VM option key cannot be matched to any known option descriptor. The builder looks up the key in the engine, compiler, and Espresso ('java') option groups; if no group knows the key (after also trying the 'java.'-prefixed form), it is rejected as unrecognized.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccessBuilder.java:218
}
return;
} else if ("log.file".equals(key)) {
OutputStream out;
try {
out = new BufferedOutputStream(Files.newOutputStream(Paths.get(value), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.APPEND));
} 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:View on GitHub (pinned to a66e9ccd1d)
Solutions
- Fix the spelling/prefix of the option: Espresso options need the 'java.' group (builder also tries the prefixed form automatically), engine options 'engine.*', compiler options 'compiler.*'
- Enumerate valid keys from the engine's OptionDescriptors (getTempEngine().getOptions() / language options) and diff them against what you pass
- After upgrading GraalVM, re-check that the option still exists; guard version-specific options behind a capability check
Example fix
// before
builder.option("java.Continue", "true"); // typo: option does not exist
// after
builder.option("java.ContinueOnInitializationError", "true"); Defensive patterns
Strategy: validation
Validate before calling
OptionDescriptors known = engine.getOptions(); // plus language 'java' options
if (known.get(key) == null) throw new IllegalArgumentException("Unknown option, available: " + known); Try / catch
catch (IllegalArgumentException e) { print available option keys near the failure to help fix the typo } Prevention
- Centralize all VM option strings as named constants instead of scattering string literals
- After a GraalVM upgrade, diff your option list against the new OptionDescriptors
When it happens
Trigger: Passing a misspelled or nonexistent option key to the builder (e.g. 'java.Continue' instead of 'java.ContinueOnInitializationError'), passing a plain-engine option without the right group prefix, or passing a HotSpot-only -XX/-H: flag that Espresso does not define.
Common situations: Typos in option names; using options that only exist in a different GraalVM/Espo version after an upgrade; copy-pasting substratevm (native-image) options into an Espresso embedder; dropping the 'java.' prefix for Espresso-specific options.
Related errors
- Invalid log level %s specified. %s'
- Invalid VM option %s specified. %s
- Out of scratch registers: %s
- Unexpected architecture name ${archName}
- Could not find option %s
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/63e1bad0ed85674b.
Report an issue: GitHub.