NationalSecurityAgency/ghidra · error · LSHException
Cannot commit self-score with the matrix scorer
Error message
Cannot commit self-score with the matrix scorer
What it means
Thrown by the no-arg commitSelfScore() on the base ExecutableScorer class, which implements many-to-many matrix scoring. The matrix scorer holds scores only in an in-memory float[][] array and has no ScoreCaching backing store, so persisting a self-score is architecturally unsupported. Only the subclass ExecutableScorerSingle overrides this method to delegate to a ScoreCaching implementation (e.g. FileScoreCaching).
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/ExecutableScorer.java:284
return score[a - 1][b - 1];
}
/**
* Retrieve the similarity score of an executable with itself
* @param a is the index of the executable
* @return its self-similarity score
* @throws LSHException if the score is not accessible
*/
public float getSelfScore(int a) throws LSHException {
return score[a - 1][a - 1];
}
/**
* Commit the singled out executables self-significance score to permanent storage
* @throws LSHException if there's a problem writing, or the operation isn't supported
*/
public void commitSelfScore() throws LSHException {
throw new LSHException("Cannot commit self-score with the matrix scorer");
}
/**
* Commit a self-significance score for a specific executable to permanent storage
* @param md5 is the 32-character md5 hash of the executable
* @param selfScore is the self-significance score
* @throws LSHException if there's a problem writing, or the operation isn't supported
*/
protected void commitSelfScore(String md5, float selfScore) throws LSHException {
throw new LSHException("Cannot commit self-score with the matrix scorer");
}
/**
* Get score of executable (as compared to our singled out executable)
* @param a is the index of the executable
* @return the score
*/
public float getScore(int a) {View on GitHub (pinned to d5f144c24d)
Solutions
- If you need to persist self-scores, construct an ExecutableScorerSingle (passing a ScoreCaching such as FileScoreCaching) instead of the base ExecutableScorer.
- If you intentionally use the matrix scorer, remove the commitSelfScore() call — the matrix stores all scores in memory and does not need persistence for its own operation.
- If you must persist from a matrix context, extract the self-score via getSelfScore(int) and write it to your own ScoreCaching implementation manually.
Example fix
// before
ExecutableScorer scorer = new ExecutableScorer();
scorer.setSingleExecutable(md5);
scorer.commitSelfScore(); // throws LSHException
// after
ExecutableScorerSingle scorer =
new ExecutableScorerSingle(new FileScoreCaching(cachePath));
scorer.setSingleExecutable(md5);
scorer.commitSelfScore(); // delegates to FileScoreCaching Defensive patterns
Strategy: type-guard
Validate before calling
if (scorer instanceof ExecutableScorerSingle) {
((ExecutableScorerSingle) scorer).commitSelfScore();
} else {
// matrix scorer: no persistence; read scores in-memory only
float selfScore = scorer.getSelfScore(scorer.getSingleExeXref());
} Type guard
public static boolean canCommitSelfScore(ExecutableScorer scorer) {
return scorer instanceof ExecutableScorerSingle;
} Try / catch
try {
scorer.commitSelfScore();
} catch (LSHException e) {
if (e.getMessage().contains("matrix scorer")) {
// expected for base ExecutableScorer; no action needed
} else {
throw e;
}
} Prevention
- Check the concrete scorer type before calling commitSelfScore.
- Use ExecutableScorerSingle whenever you need persistent self-scores.
- Design generic methods to accept ExecutableScorerSingle if they rely on commitSelfScore.
When it happens
Trigger: Calling scorer.commitSelfScore() (the no-arg overload) on an ExecutableScorer instance whose runtime type is the base ExecutableScorer rather than ExecutableScorerSingle. This happens when code instantiates ExecutableScorer directly for many-to-many comparison and then attempts to persist the singled-out executable's self-significance score.
Common situations: A developer copies code from a one-to-many (ExecutableScorerSingle) workflow into a many-to-many (ExecutableScorer) workflow and forgets that persistence is only available on the single scorer. Also seen when a generic method accepts an ExecutableScorer reference and calls commitSelfScore() without checking the concrete subclass.
Related errors
- Cannot reset singled executable
- No such register: {name}
- All trace memory is initialized
- Mapped blocks are not supported in traces
- Traces do not support externals
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/1206225b31af4885.
Report an issue: GitHub.