NationalSecurityAgency/ghidra · error · IllegalArgumentException

Could not determine option type from default value: {} = {}

Error message

Could not determine option type from default value: {} = {}

What it means

Thrown by AutoOptions.registerOptionsDefined() when an @AutoOptionDefined field's option type cannot be inferred. The annotation's type() defaults to NO_TYPE, and if the field's default value also does not map to a known OptionType (via OptionType.getOptionType), registration aborts because Ghidra cannot store or edit the option without a concrete type.

Source

Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/options/AutoOptions.java:144

				continue;
			}
			f.setAccessible(true);
			HelpLocation help = getHelpLocation(plugin.getName(), annotation.help());
			Object defaultValue;
			try {
				defaultValue = f.get(receiver);
			}
			catch (IllegalArgumentException | IllegalAccessException e) {
				throw new AssertionError(e);
			}

			OptionType type = annotation.type();
			if (type == OptionType.NO_TYPE) {
				type = OptionType.getOptionType(defaultValue);
				// TODO: OptionType does have getValueClass, if searching by class is better
			}
			if (type == OptionType.NO_TYPE) {
				throw new IllegalArgumentException(
					"Could not determine option type from default value: " + f + " = " +
						defaultValue);
			}

			String description = annotation.description();
			Class<? extends PropertyEditor> editorClass = annotation.editor();
			final PropertyEditor editor;
			if (editorClass == PropertyEditor.class || SystemUtilities.isInHeadlessMode()) {
				editor = null;
			}
			else {
				try {
					editor = editorClass.getConstructor().newInstance();
				}
				catch (InstantiationException | IllegalAccessException | IllegalArgumentException
						| InvocationTargetException | NoSuchMethodException | SecurityException e) {
					throw new IllegalArgumentException(
						"editor class must have accessible default constructor", e);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Set an explicit type() on @AutoOptionDefined (e.g. OptionType.INT, OptionType.STRING, OptionType.BOOLEAN).
  2. Ensure the field's default value is a type OptionType recognizes (String, int, double, boolean, etc.).
  3. Initialize the field so its default is non-null and type-inferable.
  4. If a custom type is needed, supply a PropertyEditor via the editor() attribute and a concrete type().

Example fix

// before
@AutoOptionDefined(description = "timeout")
private Object timeout; // null default, NO_TYPE -> throws

// after
@AutoOptionDefined(type = OptionType.INT, description = "timeout")
private int timeout = 30;
Defensive patterns

Strategy: validation

Validate before calling

OptionType t = annotation.type();
if (t == OptionType.NO_TYPE) {
  t = OptionType.getOptionType(defaultValue);
}
if (t == OptionType.NO_TYPE) {
  throw new IllegalStateException("Set explicit type() on @AutoOptionDefined for " + f);
}

Prevention

When it happens

Trigger: An @AutoOptionDefined field whose default value is null or an unsupported type, with type() left at NO_TYPE. A field typed as a custom class that OptionType does not recognize. A field with no initializer giving a null default.

Common situations: Adding an option field with a custom/complex type not covered by OptionType; forgetting to set type() on the annotation; leaving a reference field uninitialized so the default is null.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/167016fb9626476c. Report an issue: GitHub.