NationalSecurityAgency/ghidra · warning · InvalidInputException

Didn't remove external library {libName} since it isn't empt

Error message

Didn't remove external library {libName} since it isn't empty.

What it means

Thrown by ExternalProgramMerger.removeExternalLibrary when an external library still has external locations referencing it. The merger's policy is to only remove empty libraries; iter.hasNext() returning true means at least one ExternalLocation remains, so removal is aborted and InvalidInputException is raised. This protects against orphaning external location references during a merge.

Source

Thrown at Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ExternalProgramMerger.java:581

		if (s != null) {
			return (s.getSource() == SourceType.USER_DEFINED);
		}
		return false;
	}

	/**
	 * Removes the indicated external library from the indicated program version
	 * if it is empty.
	 * @param program the program
	 * @param libName the external library name
	 * @throws InvalidInputException if there is no such enterrnal library in the program
	 */
	private void removeExternalLibrary(Program program, String libName)
			throws InvalidInputException {
		ExternalManager extMgr = program.getExternalManager();
		ExternalLocationIterator iter = extMgr.getExternalLocations(libName);
		if (iter.hasNext()) {
			throw new InvalidInputException(
				"Didn't remove external library " + libName + " since it isn't empty.");
		}
		if (!extMgr.removeExternalLibrary(libName)) {
			throw new InvalidInputException("Didn't remove external library " + libName);
		}
	}

	/**
	 * Determines whether the latest external program name and my external program name are equals.
	 * @param latestName the latest external program name or null.
	 * @param myName my external program name or null.
	 * @return true if the names are equal.
	 */
	private boolean same(String latestName, String myName) {
		return SystemUtilities.isEqual(latestName, myName);
	}

	/**

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Remove or relocate the external locations in the library before attempting to remove the library.
  2. Keep the library instead of removing it; the exception is informational - catch it and append the message to infoBuf (as the merger's callers already do).
  3. Resolve the merge conflict in the GUI so the library/locations are consistent before check-in.
  4. In scripting, call extMgr.getExternalLocations(libName) first and only remove when iter is empty.

Example fix

// before
removeExternalLibrary(program, libName);
// library has locations -> InvalidInputException

// after
ExternalManager extMgr = program.getExternalManager();
if (!extMgr.getExternalLocations(libName).hasNext()) {
    extMgr.removeExternalLibrary(libName);
} else {
    infoBuf.append("Library " + libName + " not removed: still has external locations\n");
}
Defensive patterns

Strategy: validation

Validate before calling

ExternalManager extMgr = program.getExternalManager();
boolean empty = !extMgr.getExternalLocations(libName).hasNext();
if (!empty) {
    // do not call removeExternalLibrary; relocate or keep the library
}

Type guard

boolean isExternalLibraryEmpty(Program p, String libName) {
    return !p.getExternalManager().getExternalLocations(libName).hasNext();
}

Try / catch

try {
    removeExternalLibrary(program, libName);
} catch (InvalidInputException e) {
    if (e.getMessage().contains("isn't empty")) {
        // keep the library; log and continue
        infoBuf.append(e.getMessage() + "\n");
    } else throw e;
}

Prevention

When it happens

Trigger: During a multi-user program merge (version-control check-in), the merger attempts to remove an external library (because latest or 'my' version dropped it) but the result program still has external locations pointing into that library. Triggered by autoMergeWhenOnlyLatestChanged / autoMergeWhenOnlyMyChanged when latestName or myName is null.

Common situations: One branch deleted a library while another branch (or the result) still references its locations. Merge of programs where external locations were added but the library was simultaneously renamed/removed. Re-entrant merge state.

Related errors


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