NationalSecurityAgency/ghidra · error · IllegalArgumentException

Function list cannot be empty

Error message

Function list cannot be empty

What it means

Thrown by the SFQueryInfo constructor when the Set<FunctionSymbol> functions is non-null but empty (isEmpty()). A similar-function query needs at least one source function to generate signatures; an empty set is an invalid request. Second ordered check after the null check.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/facade/SFQueryInfo.java:60

	private QueryNearest queryNearest;
	private BSimFilter bsimFilter;
	private PreFilter preFilter;

	/**
	 * Constructs a query request with default parameters.
	 * @param functions required--a set of functions (at least one) for which similar functions
	 *                  will searched.  All functions must be from the same program.
	 * @throws IllegalArgumentException if {@code functions} is {@code null}/empty or functions
	 * are from multiple programs.  
	 */
	public SFQueryInfo(Set<FunctionSymbol> functions) {
		if (functions == null) {
			throw new IllegalArgumentException("Function list cannot be null");
		}

		if (functions.isEmpty()) {
			throw new IllegalArgumentException("Function list cannot be empty");
		}

		this.functions = functions;
		for (FunctionSymbol s : functions) {
			if (program == null) {
				program = s.getProgram();
			}
			else if (program != s.getProgram()) {
				throw new IllegalArgumentException(
					"all function symbols are not from the same program");
			}
		}
		queryNearest = new QueryNearest();
		bsimFilter = new BSimFilter();
		preFilter = new PreFilter();
	}

	/**

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Guard at the action entry: skip SFQueryInfo construction when the set is empty and notify the user.
  2. Validate selection contains at least one function symbol before enabling the search action.
  3. In loops, continue rather than construct when the resolved set is empty.

Example fix

// before
Set<FunctionSymbol> syms = getSelectedFunctionSymbols();
SFQueryInfo info = new SFQueryInfo(syms);
// after
Set<FunctionSymbol> syms = getSelectedFunctionSymbols();
if (syms == null || syms.isEmpty()) { return; }
SFQueryInfo info = new SFQueryInfo(syms);
Defensive patterns

Strategy: validation

Validate before calling

if (functions == null || functions.isEmpty()) {
    setStatusMessage("Select one or more functions");
    return;
}
SFQueryInfo info = new SFQueryInfo(functions);

Type guard

static boolean nonEmptyFunctions(Set<FunctionSymbol> fns) {
    return fns != null && !fns.isEmpty();
}

Try / catch

try {
    new SFQueryInfo(functions);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("empty")) { /* inform user */ }
}

Prevention

When it happens

Trigger: new SFQueryInfo(Set.of()) or a selection set that matched zero functions.

Common situations: User invokes BSim search with nothing selected; a filter excluded all symbols; a batch loop hit an item with no symbols.

Related errors


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