NationalSecurityAgency/ghidra · error · LSHException
Cannot reset singled executable
Error message
Cannot reset singled executable
What it means
Thrown by ExecutableScorerSingle.setSingleExecutable() when singleExeXref is already >= 0, meaning a singled-out executable has already been established. ExecutableScorerSingle is designed for a one-to-many comparison where exactly one executable is the focus; the single is immutable once set because the scorer allocates a single-row score array and pairs functions relative to it.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/ExecutableScorerSingle.java:58
* must be provided.
* @param cache is the self-score cacher or null
* @throws LSHException for problems initializing the cache
*/
public ExecutableScorerSingle(ScoreCaching cache) throws LSHException {
super(); // Turn on single executable filtering
singleScore = null;
scoreCache = cache;
if (scoreCache == null) {
scoreCache = new TemporaryScoreCaching();
}
simThreshold = scoreCache.getSimThreshold();
sigThreshold = scoreCache.getSigThreshold();
}
@Override
public void setSingleExecutable(String md5) throws LSHException {
if (singleExeXref >= 0) {
throw new LSHException("Cannot reset singled executable");
}
super.setSingleExecutable(md5);
}
@Override
public int countSelfScores() {
Iterator<ExecutableRecord> iter = executableSet.getExecutableRecordSet().iterator();
int count = 0;
while (iter.hasNext()) {
ExecutableRecord exe = iter.next();
try {
scoreCache.getSelfScore(exe.getMd5());
count += 1;
}
catch (LSHException e) {
// Don't increment count
}
}View on GitHub (pinned to d5f144c24d)
Solutions
- Construct a new ExecutableScorerSingle instance for each new executable you want to compare.
- Call resetStorage(simThresh, sigThresh) which nulls singleScore and resets the cache — but note this does NOT reset singleExeXref, so you still need a fresh instance.
- Restructure your loop to create the scorer inside the loop body rather than reusing one outside.
Example fix
// before
ExecutableScorerSingle scorer = new ExecutableScorerSingle(cache);
for (String md5 : md5List) {
scorer.setSingleExecutable(md5); // throws on 2nd iteration
}
// after
for (String md5 : md5List) {
ExecutableScorerSingle scorer = new ExecutableScorerSingle(cache);
scorer.setSingleExecutable(md5);
} Defensive patterns
Strategy: validation
Validate before calling
// Check before calling (singleExeXref is protected; track externally)
boolean alreadySet = (scorer.getSingleExeXref() >= 0); // if exposed
if (!alreadySet) {
scorer.setSingleExecutable(md5);
} Try / catch
try {
scorer.setSingleExecutable(md5);
} catch (LSHException e) {
if (e.getMessage().contains("Cannot reset")) {
// create a fresh scorer for the new executable
scorer = new ExecutableScorerSingle(cache);
scorer.setSingleExecutable(md5);
} else throw e;
} Prevention
- Construct a new ExecutableScorerSingle for each executable comparison rather than reusing.
- Track whether setSingleExecutable has been called in your own code.
- Avoid sharing a single scorer across multiple comparison targets.
When it happens
Trigger: Calling setSingleExecutable(md5) a second time on the same ExecutableScorerSingle instance. The first successful call sets singleExeXref to a non-negative value; any subsequent call throws before reaching the superclass.
Common situations: Reusing an ExecutableScorerSingle instance across multiple queries (e.g. in a loop comparing different executables) without constructing a fresh scorer each iteration. Also occurs when merging two workflows that each set the single executable.
Related errors
- Cannot commit self-score with the matrix scorer
- Self-score not recorded for {md5}
- database in use
- Missing username for password change
- No password provided
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/69abfde14d39d52a.
Report an issue: GitHub.