NationalSecurityAgency/ghidra · error · LSHException

Self-score not recorded for

Error message

Self-score not recorded for 

What it means

Thrown by TemporaryScoreCaching.getSelfScore when the in-memory cache (TreeMap) does not contain an entry for the given md5. Unlike TableScoreCaching, TemporaryScoreCaching has no database fallback — it only serves scores that were explicitly committed into memory. A cache miss is therefore a hard error. This is used for transient/ephemeral scoring sessions.

Source

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

			else {
				for (ExecutableRecord exeRec : exeSet) {
					if (!cacheMap.containsKey(exeRec.getMd5())) {
						missing.add(exeRec);
					}
				}
			}
		}
	}

	@Override
	public float getSelfScore(String md5) throws LSHException {
		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 {
		if (cacheMap == null) {
			cacheMap = new TreeMap<String, Float>();
		}
		cacheMap.put(md5, score);
	}

	@Override
	public double getSimThreshold() throws LSHException {
		return simThreshold;
	}

	@Override
	public double getSigThreshold() throws LSHException {
		return sigThreshold;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure commitSelfScore is called for every md5 you intend to query before calling getSelfScore.
  2. If you need persistence across sessions, use TableScoreCaching (database-backed) instead of TemporaryScoreCaching.
  3. Pre-populate the cache in a single pass: iterate all vectors, compute self-scores, commit, then query.
  4. Guard with a contains check if the cache exposes it, or maintain your own set of scored md5s.

Example fix

// before
TemporaryScoreCaching cache = new TemporaryScoreCaching();
float s = cache.getSelfScore(md5); // throws — never committed

// after
TemporaryScoreCaching cache = new TemporaryScoreCaching();
for (String id : allMd5s) {
    cache.commitSelfScore(id, computeSelfScore(id));
}
float s = cache.getSelfScore(md5);
Defensive patterns

Strategy: validation

Validate before calling

// Track scored md5s to validate before querying a TemporaryScoreCaching.
Set<String> scored = new HashSet<>();
void commit(String md5, float s) { cache.commitSelfScore(md5, s); scored.add(md5); }
float get(String md5) throws LSHException {
    if (!scored.contains(md5)) throw new IllegalStateException("unscored: "+md5);
    return cache.getSelfScore(md5);
}

Try / catch

try {
    return cache.getSelfScore(md5);
} catch (LSHException e) {
    // No DB fallback for TemporaryScoreCaching; generate and commit
    float s = generateSelfScore(md5);
    cache.commitSelfScore(md5, s);
    return cache.getSelfScore(md5);
}

Prevention

When it happens

Trigger: Calling getSelfScore(md5) on a TemporaryScoreCaching before commitSelfScore(md5, score) has been called for that md5. Also when the cache was reset (cacheMap set to null or cleared) between commit and query. Any code path that queries a self-score it never stored.

Common situations: Using a TemporaryScoreCaching for a short-lived scoring session but querying a vector whose score was computed in a different session/cache instance. Forgetting to populate the cache for all vectors in a batch before issuing similarity queries that read self-scores. Resetting the cache mid-run.

Related errors


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