skylot/jadx · error · RuntimeException

Setter invoke failed for option: ${option.name}, value: ${pa

Error message

Setter invoke failed for option: ${option.name}, value: ${parsedValue}

What it means

Thrown by BasePluginOptionsBuilder.parseOption when the setter Consumer (the field-assignment lambda) for a parsed option value raises an exception. Jadx catches any exception from option.getSetter().accept(parsedValue) and re-throws it as a RuntimeException with the option name and the already-parsed value. This distinguishes setter-time failures from parse-time failures (error 41).

Source

Thrown at jadx-core/src/main/java/jadx/api/plugins/options/impl/BasePluginOptionsBuilder.java:110

	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'");
	}

	private <T> OptionBuilder<T> addOption(OptionBuilder<T> optionData) {
		this.options.add((OptionData<?>) optionData);
		return optionData;
	}

View on GitHub (pinned to e738a26571)

Solutions

  1. Inspect the cause exception in the stack trace to identify which constraint in the setter lambda failed.
  2. If the setter validates ranges or formats, adjust the option value to satisfy the constraint.
  3. If writing the plugin, separate validation from the setter — validate in the parser instead, or catch expected conditions in the setter and rethrow with a clear message.
  4. Ensure the setter handles the option's defaultValue gracefully when the user omits the option (value == null path yields defaultValue).

Example fix

// before (plugin setter with implicit constraint)
.option("port")
    .setter(v -> { if (v < 1024) throw new IllegalArgumentException("port too low"); this.port = v; })
// invoked with myplugin.port=80 → triggers 'Setter invoke failed'

// after: supply a privileged port value
// myplugin.port=8080
Defensive patterns

Strategy: try-catch

Try / catch

try {
    optionsBuilder.setOptions(userOptionsMap);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Setter invoke failed for option:")) {
        // The parsed value was valid but the setter rejected it
        LOG.warn("Option setter rejected value: {}", e.getMessage(), e);
    } else {
        throw e; // not a setter failure, rethrow
    }
}

Prevention

When it happens

Trigger: A plugin registers an option whose setter lambda (via OptionBuilder.setter(Consumer)) performs additional validation or side-effects and throws. For example, a setter that rejects null, validates a range, or calls a method that fails. The trigger is that parsing succeeded but assignment did not.

Common situations: A custom setter validates constraints (e.g., rejects a port number < 1024) and throws. A setter writes to a collection or object that is in an invalid state. A nullable handling mismatch where the default value is null but the setter expects non-null. Typically a plugin-internal programming error rather than user input error.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/338e40e220c8af31. Report an issue: GitHub.