skylot/jadx · error · RuntimeException
Parse failed for option: ${option.name}, value: ${value}
Error message
Parse failed for option: ${option.name}, value: ${value} What it means
Thrown by BasePluginOptionsBuilder.parseOption when the registered parser function for a plugin option throws any exception while converting the user-supplied string value. Jadx wraps the original exception in a RuntimeException so the plugin options builder can uniformly report parse failures with the option name and raw value. The cause chain preserves the underlying exception (e.g., NumberFormatException from Integer::parseInt).
Source
Thrown at jadx-core/src/main/java/jadx/api/plugins/options/impl/BasePluginOptionsBuilder.java:104
for (OptionData<?> option : options) {
parseOption(option, map.get(option.name));
}
}
@Override
public List<OptionDescription> getOptionsDescriptions() {
return Collections.unmodifiableList(options);
}
private static <T> void parseOption(OptionData<T> option, @Nullable String value) {
T parsedValue;
if (value == null) {
parsedValue = option.defaultValue;
} else {
try {
parsedValue = option.getParser().apply(value);
} catch (Exception e) {
throw new RuntimeException("Parse failed for option: " + option.name + ", value: " + value, e);
}
}
try {
option.getSetter().accept(parsedValue);
} catch (Exception e) {
throw new RuntimeException("Setter invoke failed for option: " + option.name + ", value: " + parsedValue, e);
}
}
private static boolean parseBoolOption(String name, String val) {
String valLower = val.trim().toLowerCase(Locale.ROOT);
if (valLower.equals("yes") || valLower.equals("true")) {
return true;
}
if (valLower.equals("no") || valLower.equals("false")) {
return false;
}
throw new IllegalArgumentException("Unknown value '" + val + "' for option '" + name + "', expect: 'yes' or 'no'");View on GitHub (pinned to e738a26571)
Solutions
- Check the option's declared type and values (via getOptionsDescriptions) and supply a value that the option's parser accepts.
- For integer options, ensure the value is a valid base-10 integer with no surrounding text.
- For enum options, pass one of the documented enum constant names (case is handled by the default enumOption parser, but verify the specific plugin).
- If writing the plugin, make the custom parser more lenient or throw a descriptive IllegalArgumentException so the wrapped message is clear.
Example fix
// before
option("depth").parser(Integer::parseInt)
// invoked with: myplugin.depth=12x
// after (user fix): supply a valid integer
// myplugin.depth=12
// after (plugin author fix): validate before parse
option("depth").parser(s -> {
try { return Integer.parseInt(s.trim()); }
catch (NumberFormatException e) {
throw new IllegalArgumentException("depth must be an integer, got: " + s);
}
}) Defensive patterns
Strategy: validation
Validate before calling
// Check option description before parsing to validate user input
List<OptionDescription> descs = optionsBuilder.getOptionsDescriptions();
for (OptionDescription desc : descs) {
if (desc.getName().equals(optionName)) {
// For numeric options, verify the value is parseable
if (desc.getType() == OptionType.NUMBER) {
try { Integer.parseInt(userValue); }
catch (NumberFormatException e) {
throw new IllegalArgumentException(optionName + " requires an integer");
}
}
}
} Type guard
static boolean optionValueIsParsable(OptionDescription desc, String value) {
if (value == null) return true;
switch (desc.getType()) {
case NUMBER:
return value.matches("-?\\d+");
case BOOLEAN:
String lower = value.trim().toLowerCase(Locale.ROOT);
return lower.equals("yes") || lower.equals("no")
|| lower.equals("true") || lower.equals("false");
case STRING:
default:
return true;
}
} Try / catch
try {
optionsBuilder.setOptions(userOptionsMap);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Parse failed for option:")) {
LOG.error("Invalid option value: {}", e.getMessage());
} else {
throw e;
}
} Prevention
- Validate option values against their declared OptionType before calling setOptions.
- For enum options, check the value against the declared values list in OptionDescription.
- When building a custom parser, throw IllegalArgumentException with a human-readable message so the wrapped RuntimeException is clear.
When it happens
Trigger: A plugin registers an option via intOption(name) (whose parser is Integer::parseInt) and the user supplies a non-numeric string. Or a custom OptionBuilder.parser(Function) lambda throws on malformed input. The error fires inside setOptions(map) -> parseOption(option, value) when option.getParser().apply(value) raises.
Common situations: User passes --plugin-option myplugin.depth=abc to an integer option. A enumOption parser receives a value that does not match any enum constant (the valueOf call throws IllegalArgumentException). Locale-specific parsing (e.g., decimal separators) in a custom parser fails on unexpected input.
Related errors
- Unknown value '${val}' for option '${key}', expect: 'yes' or
- Setter invoke failed for option: ${option.name}, value: ${pa
- Unknown value '${val}' for option '${name}', expect: 'yes' o
- Failed to apply options for plugin: {}
- Read limit exceeded
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/a9b08193a085e6ac.
Report an issue: GitHub.