NationalSecurityAgency/ghidra · warning · IllegalArgumentException

Register not found for program

Error message

Register {regName} not found for program {programName}

What it means

Thrown by FunctionStartRFParams.setRegistersAndValues(csv) when a register name parsed from the CSV is not present in the training source program — trainingSource.getRegister(regName) returned null. The register must be a real context register defined in the program's language for it to be constrainable. State is cleared before throwing.

Solutions

  1. Use program.getLanguage().getRegisters() (or getRegister(name)) to enumerate valid register names for the training program and pass only those.
  2. Correct the spelling/architecture of the register name in the CSV.
  3. If the register should exist, verify the correct language/program is the trainingSource.

Example fix

// before
params.setRegistersAndValues("rax=0"); // ARM program

// after
Register r = trainingSource.getRegister("r0");
params.setRegistersAndValues(r == null ? "" : "r0=0");
Defensive patterns

Strategy: validation

Validate before calling

import ghidra.program.model.listing.Program;
String csv = "cs=0x33,ds=0x2b";
StringBuilder ok = new StringBuilder();
for (String part : csv.split(",")) {
    String[] kv = part.split("=", -1);
    String reg = kv[0].trim();
    if (trainingSource.getRegister(reg) != null) {
        if (ok.length() > 0) ok.append(",");
        ok.append(part);
    } // else skip unknown register
}
params.setRegistersAndValues(ok.toString());

Type guard

null

Try / catch

try {
    params.setRegistersAndValues(csv);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("not found for program")) {
        // fetch valid registers from trainingSource and re-prompt
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a register name that does not exist for the program's language (e.g. 'rax' for an ARM program, or a typo), or a context register that the Sleigh language does not expose.

Common situations: Copying register constraints from a different architecture; mistyping a register; using a processor context register that the language marks as hidden/unnamed.

Related errors


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

Appendix: source

Thrown at Ghidra/Extensions/MachineLearning/src/main/java/ghidra/machinelearning/functionfinding/FunctionStartRFParams.java:199

	 * @param csv the list to parse
	 * @throws IllegalArgumentException if there are any parsing errors
	 */
	public void setRegistersAndValues(String csv) {
		contextRegisterNames = new ArrayList<>();
		contextRegisterVals = new ArrayList<>();
		String[] parts = csv.split(",");
		for (String part : parts) {
			String[] regValPair = part.split("=");
			if (regValPair.length != 2) {
				contextRegisterNames.clear();
				contextRegisterVals.clear();
				throw new IllegalArgumentException("Error parsing register=value string " + part);
			}
			String regName = regValPair[0].trim();
			if (trainingSource.getRegister(regName) == null) {
				contextRegisterNames.clear();
				contextRegisterVals.clear();
				throw new IllegalArgumentException(
					"Register " + regName + " not found for program " + trainingSource.getName());
			}
			contextRegisterNames.add(regName);
			BigInteger bigInt = new BigInteger(regValPair[1].trim());
			contextRegisterVals.add(bigInt);
		}
	}

	/**
	 * Parses a CSV into a sorted list of distinct integer values (duplicates are ignored).  Returns
	 * an empty list of a parse error is encountered.
	 * @param csv csv string to parse
	 * @return sorted list  
	 */
	public static List<Integer> parseIntegerCSV(String csv) {
		if (StringUtils.isBlank(csv)) {
			throw new IllegalArgumentException("Entry cannot be blank");
		}

View on GitHub (pinned to d5f144c24d)