NationalSecurityAgency/ghidra · error · IllegalArgumentException

Missing required parameter '%s' (%s)

Error message

Missing required parameter '%s' (%s)

What it means

Thrown by LaunchParameter.get() when a required launch parameter is absent from the arguments map. The message interpolates the parameter's display name and internal name. This is part of the Trace RMI launch-argument handling: each launch parameter has a name, type, default value, and a required flag, and get() retrieves it from a supplied argument map.

Source

Thrown at Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/LaunchParameter.java:97

			throw new IllegalArgumentException("Type errors: " + typeErrors);
		}
		return arguments;
	}

	public static Map<String, LaunchParameter<?>> mapOf(LaunchParameter<?>... parameters) {
		return mapOf(Arrays.asList(parameters));
	}

	public ValStr<T> decode(String string) {
		return decoder.decodeValStr(string);
	}

	public ValStr<T> get(Map<String, ValStr<?>> arguments) {
		if (arguments.containsKey(name)) {
			return ValStr.cast(type, arguments.get(name));
		}
		if (required) {
			throw new IllegalArgumentException(
				"Missing required parameter '%s' (%s)".formatted(display, name));
		}
		return defaultValue;
	}

	public void set(Map<String, ValStr<?>> arguments, ValStr<T> value) {
		arguments.put(name, value);
	}
}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Before calling get(), check arguments.containsKey(name) and supply all required parameters' values first.
  2. Populate the arguments map by iterating over the method's declared parameters and providing a value for each required one.
  3. If the parameter should be optional, ensure it was declared with required=false and/or a non-null default value.

Example fix

// before
ValStr<T> val = param.get(arguments); // throws if missing & required

// after
if (!arguments.containsKey(param.name) && param.required) {
    throw new IllegalStateException("Must supply " + param.name);
}
ValStr<T> val = param.get(arguments);
Defensive patterns

Strategy: validation

Validate before calling

// Before calling param.get(arguments):
Set<String> required = params.stream()
    .filter(LaunchParameter::required)
    .map(p -> p.name)
    .collect(Collectors.toSet());
Set<String> missing = new HashSet<>(required);
missing.removeAll(arguments.keySet());
if (!missing.isEmpty()) {
    throw new IllegalStateException("Missing: " + missing);
}

Type guard

// No type narrowing needed; guard on map contents
static boolean hasAllRequired(List<LaunchParameter> params,
        Map<String, ValStr<?>> args) {
    return params.stream().filter(LaunchParameter::required)
        .allMatch(p -> args.containsKey(p.name));
}

Try / catch

try {
    ValStr<T> v = param.get(arguments);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Missing required parameter")) {
        // prompt user for the value, then retry
    } else throw e;
}

Prevention

When it happens

Trigger: Calling LaunchParameter.get(arguments) where arguments is a Map<String,ValStr<?>> missing the entry for this parameter's name, while the parameter's required flag is true and no default value exists.

Common situations: Building a trace RMI launch invocation (e.g., invoking a debugger target launch method) without supplying all mandatory arguments; UI code that constructs the argument map from partially-filled form fields before the user finished entering required values.

Related errors


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