NationalSecurityAgency/ghidra · error · LSHException

Could not locate vector by id

Error message

Could not locate vector by id

What it means

Thrown by ExecutableComparison.buildSeedVector when a QueryVectorId query for a single vector id returns null or does not contain exactly one result. This means the vector id could not be resolved to a concrete vector — the id may be stale, the vector deleted, or a query failure occurred.

Source

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

		query.manage.attachSignature(function, signature);

		query.manage.transferSettings(scorer.executableSet);
		query.thresh = threshold;
		return query;
	}

	/**
	 * Look up a single vector by id
	 * @param id is the Long id of the vector
	 * @return the matching vector result
	 * @throws LSHException if the vector does not exist
	 */
	private VectorResult buildSeedVector(Long id) throws LSHException {
		QueryVectorId query = new QueryVectorId();
		query.vectorIds.add(id);
		ResponseVectorId response = query.execute(database);
		if (response == null || response.vectorResults.size() != 1) {
			throw new LSHException("Could not locate vector by id");
		}
		return response.vectorResults.get(0);
	}

	/**
	 * Pull one ID out of the workList, look-up its corresponding vector, and query for nearby vectors.
	 * Add IDs of the close vectors (that have not been seen before) to the workList
	 * Use vectorMap to keep track of what's been seen/queried before
	 * @param workList is the current list of IDs yet to be processed for the cluster
	 * @param threshold defines how similar "close" vectors are
	 * @return the VectorResult of the next ID
	 * @throws LSHException if something goes wrong during a query
	 */
	private VectorResult queryVectorForCluster(TreeMap<Long, VectorResult> workList,
		double threshold)
		throws LSHException {
		Entry<Long, VectorResult> entry = workList.pollFirstEntry();
		VectorResult currentVector = entry.getValue();

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Verify the vector id still exists before building the seed (re-query or check id validity).
  2. Skip stale ids in cluster processing rather than failing.
  3. Ensure no concurrent deletions occur during active comparisons.
  4. Inspect db.getLastError() if the response was null (query failure).

Example fix

// before
VectorResult v = buildSeedVector(id); // throws if id stale
// after
QueryVectorId q = new QueryVectorId();
q.vectorIds.add(id);
ResponseVectorId resp = q.execute(database);
if (resp == null || resp.vectorResults.size() != 1) {
    return null; // skip stale id
}
Defensive patterns

Strategy: validation

Validate before calling

// Before seeding, verify id liveness:
QueryVectorId q = new QueryVectorId();
q.vectorIds.add(id);
ResponseVectorId resp = q.execute(database);
if (resp != null && resp.vectorResults.size() == 1) {
    // safe to proceed
} else { /* skip id */ }

Try / catch

catch (LSHException e) { if (e.getMessage().contains("Could not locate vector")) { /* skip this id, continue clustering */ } }

Prevention

When it happens

Trigger: Looking up a vector by id (QueryVectorId) where the id is no longer present in the database, or the query fails. Called when building a seed vector for a cluster and the VectorResult was not already cached in the work list.

Common situations: Stale vector id references after functions/executables were deleted from the database; concurrent modification (deletion during a comparison run); corrupted id index; transient query failure.

Related errors


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