NationalSecurityAgency/ghidra · error · LSHException

Could not recover cached scores: {e.getMessage()}

Error message

Could not recover cached scores: {e.getMessage()}

What it means

Thrown by FileScoreCaching.getSelfScore() as a wrapper around any IOException emitted by loadCache(). This is the user-facing LSHException that surfaces cache-load failures (missing threshold lines, bad lines, unreadable file, permission errors) when a caller tries to look up a self-score by md5.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/FileScoreCaching.java:79

			String[] split = floatString.split(" ");
			if (split.length != 2 || split[0].length() != 32) {
				reader.close();
				throw new IOException("Bad line in score file");
			}
			float val = Float.parseFloat(split[1]);
			cacheMap.put(split[0], val);
			floatString = reader.readLine();
		}
		reader.close();
	}

	@Override
	public float getSelfScore(String md5) throws LSHException {
		try {
			loadCache();
		}
		catch (IOException e) {
			throw new LSHException("Could not recover cached scores: " + e.getMessage());
		}
		if (cacheMap != null) {
			Float val = cacheMap.get(md5);
			if (val != null) {
				return val.floatValue();
			}
		}
		throw new LSHException("Self-score not recorded for " + md5);
	}

	@Override
	public void commitSelfScore(String md5, float score) throws LSHException {
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(storageFile, true));
			if (cacheMap == null) {
				writer.write(Double.toString(simThreshold));
				writer.newLine();
				writer.write(Double.toString(sigThreshold));

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Inspect the wrapped IOException message (appended after the colon) to identify the root cause — it will be one of the specific loadCache errors.
  2. Delete or reset the corrupt cache file via resetStorage(simThresh, sigThresh) and regenerate.
  3. Verify filesystem permissions and that the cache path is accessible to the process.

Example fix

// before
try {
    float score = cache.getSelfScore(md5);
} catch (LSHException e) {
    // e.getMessage() == "Could not recover cached scores: <ioMsg>"
}

// after — reset and regenerate on cache corruption
catch (LSHException e) {
    cache.resetStorage(simThresh, sigThresh);
    // re-run scoring to repopulate, then retry
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate cache file integrity before querying scores
File cacheFile = new File(cachePath);
if (cacheFile.exists() && cacheFile.length() < 10) {
    cacheFile.delete(); // too small to be valid
}

Try / catch

try {
    float score = cache.getSelfScore(md5);
} catch (LSHException e) {
    if (e.getMessage().startsWith("Could not recover")) {
        cache.resetStorage(simThresh, sigThresh);
        // re-run scoring to repopulate, then retry
    } else throw e;
}

Prevention

When it happens

Trigger: Calling getSelfScore(md5) when the underlying cache file is corrupt, truncated, missing header lines, has a bad data line, or is unreadable due to I/O or permissions. The original IOException's message is appended for diagnostics.

Common situations: A score cache file got corrupted by a crashed run, manual editing, or a disk-full condition. Permissions on the cache file or directory prevent reading. The file is on a network mount that became unavailable.

Related errors


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