NationalSecurityAgency/ghidra · error · IllegalArgumentException
{}-annotated method {} cannot have more than two parameters
Error message
{}-annotated method {} cannot have more than two parameters What it means
Thrown by AutoOptionsListener.MethodOptionSetter when an @AutoOptionConsumed-annotated method declares more than two parameters. The framework only supports zero, one (new or old value), or two (old+new) parameters; a larger arity has no defined value mapping and is rejected at setter-construction time.
Source
Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/options/AutoOptionsListener.java:157
}
else if (parameters[0].getAnnotation(OldValue.class) != null) {
if (parameters[1].getAnnotation(OldValue.class) != null) {
throw new IllegalArgumentException("Cannot apply " +
OldValue.class.getName() + " to both parameters of " + method);
}
this.order = ParamOrder.OLD_NEW;
}
else {
if (parameters[1].getAnnotation(NewValue.class) != null) {
this.order = ParamOrder.OLD_NEW;
}
else {
this.order = ParamOrder.NEW_OLD;
}
}
}
else {
throw new IllegalArgumentException(AutoOptionConsumed.class + "-annotated method " +
method + " cannot have more than two parameters");
}
}
@Override
public void set(R receiver, Object newValue, Object oldValue) {
Object[] args = order.populate(oldValue, newValue);
try {
method.invoke(receiver, args);
}
catch (IllegalArgumentException | IllegalAccessException e) {
String argsStr = StringUtils.join(args, ",");
// Don't throw, so other consumers get updated
Msg.error(this,
"Could not invoke " + method + "(" + argsStr + ") for option " + key, e);
}
catch (InvocationTargetException e) {
Throwable cause = e.getCause();View on GitHub (pinned to d5f144c24d)
Solutions
- Reduce the method to 0, 1, or 2 parameters, using only old/new value slots.
- Move extra context into a field on the receiver or obtain it inside the method body.
- Split logic across a minimal @AutoOptionConsumed method that delegates to a helper with more args.
Example fix
// before
@AutoOptionConsumed("my.opt")
void onChange(PluginTool tool, int newVal, int oldVal) { ... } // 3 params
// after
@AutoOptionConsumed("my.opt")
void onChange(@NewValue int newVal, @OldValue int oldVal) {
doChange(this.tool, newVal, oldVal);
} Defensive patterns
Strategy: validation
Validate before calling
int n = method.getParameterCount();
if (n > 2) {
throw new IllegalStateException(
"@AutoOptionConsumed method must have 0-2 params: " + method);
} Prevention
- Limit @AutoOptionConsumed methods to 0, 1, or 2 parameters.
- Move extra context to receiver fields.
- Run a wiring test that scans all consumed-option methods.
When it happens
Trigger: An @AutoOptionConsumed method with three or more parameters, e.g. void onChange(String name, int newVal, int oldVal). Adding auxiliary parameters (a context or source) beyond the old/new pair.
Common situations: Refactoring a handler to take extra context arguments; copy-pasting a method signature from elsewhere without trimming to the supported arity; misunderstanding the supported parameter shapes.
Related errors
- Could not determine option type from default value: {} = {}
- Cannot apply {} to both parameters of {}
- Service receiver method may take only one parameter
- editor class must have accessible default constructor
- Unsupported value: {}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/ea7e15c54ca60dd0.
Report an issue: GitHub.