NationalSecurityAgency/ghidra · warning · IllegalArgumentException

Invalid element {part} - must be non-negative

Error message

Invalid element {part} - must be non-negative

What it means

Thrown by parseIntegerCSV(csv) when an element parses to an Integer (via Integer.decode, so 0x.. / 0.. / decimal) but the value is negative. The method only accepts non-negative integers because they represent byte counts/offsets for feature extraction. Note: a non-numeric element throws NumberFormatException from Integer.decode, not this message.

Source

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

	 * 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");
		}
		String trimmed = csv.trim();
		if (trimmed.startsWith(",") || trimmed.endsWith(",")) {
			throw new IllegalArgumentException("String must not begin or end with a comma");
		}
		Set<Integer> results = new HashSet<>();
		String[] parts = trimmed.split(",");
		for (String part : parts) {
			Integer i = Integer.decode(part.trim());
			if (i < 0) {
				throw new IllegalArgumentException(
					"Invalid element " + part + " - must be non-negative");
			}
			results.add(i);
		}
		return results.stream().sorted().collect(Collectors.toList());
	}

	/**
	 * Returns the {@link AddressSet} of function entries in the source program.
	 * <P>
	 * NB: Invoke {@link FunctionStartRFParams#computeFuncEntriesAndInteriors} before
	 * invoking this method.
	 * @return set of entries
	 */
	public AddressSet getFuncEntries() {
		return funcEntries;
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Use only non-negative values (0 and positive integers).
  2. Sanitize/abs the values before parsing if a sign was unintended, or reject negative input in the UI.
  3. Avoid out-of-range hex that Integer.decode maps to negative (use values < 0x80000000).

Example fix

// before
parseIntegerCSV("1,-2,4"); // throws

// after
parseIntegerCSV("1,2,4");
Defensive patterns

Strategy: validation

Validate before calling

public static boolean allNonNegative(String csv) {
    for (String part : csv.split(",")) {
        try {
            if (Integer.decode(part.trim()) < 0) return false;
        } catch (NumberFormatException e) { return false; }
    }
    return true;
}

Type guard

null

Try / catch

try {
    List<Integer> r = FunctionStartRFParams.parseIntegerCSV(csv);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("must be non-negative")) {
        // reject/abs the offending element and re-prompt
    } else throw e;
}

Prevention

When it happens

Trigger: parseIntegerCSV("1,-2,4"); parseIntegerCSV("-1"); any element that is a valid but negative integer.

Common situations: User entering a negative byte offset/count; a config derived from a signed field that went negative; hex like '0xFFFFFFFF' decoded to a negative int.

Related errors


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