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

  1. 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.*'
  2. Enumerate valid keys from the engine's OptionDescriptors (getTempEngine().getOptions() / language options) and diff them against what you pass
  3. 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

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


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