NationalSecurityAgency/ghidra · error · LSHException
${database.getLastError().message}
Error message
${database.getLastError().message} What it means
Thrown as an LSHException when a staged BSim query execution returns a null QueryResponseRecord, indicating the database failed to process the query. The actual cause is obtained from database.getLastError().message, which holds the last BSimError recorded by the underlying FunctionDatabase. This wraps the database-layer error so callers of SimilarFunctionQueryService see a consistent exception type.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/facade/SimilarFunctionQueryService.java:332
BSimQuery<?> stagedQuery = stagingManager.getQuery();
QueryResponseRecord response = stagedQuery.execute(database);
if (response != null) {
if (globalResponse != response) {
globalResponse.mergeResults(response); // Merge the staged response with the global response
}
listener.resultAdded(response);
haveMore = stagingManager.nextStage();
if (haveMore) {
stagedQuery.clearResponse(); // Make space for next stage
}
monitor.setProgress(stagingManager.getQueriesMade());
}
else {
throw new LSHException(database.getLastError().message);
}
}
return globalResponse;
}
/**
* Return the {@link BSimServerInfo server info object} for this database
* @return the server info object or null if not currently associated with
* a {@link FunctionDatabase}.
*/
public BSimServerInfo getServerInfo() {
if (database == null) {
return null;
}
return database.getServerInfo();
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Check the message string from database.getLastError() (surfaced via LSHException.getMessage()) to find the underlying database error and address that root cause.
- Verify the BSim server is reachable and healthy (use SimilarFunctionQueryService.getDatabaseStatus() to confirm Status.Ready before querying).
- Reduce the number of stages or functions per query to shorten individual round-trips, reducing exposure to mid-query failures.
- If the error indicates a layout/version mismatch, regenerate or migrate the BSim database to match the client's LAYOUT_VERSION.
- Implement a retry with re-initialization (call initializeDatabase again) if the error is transient (network blip, server restart).
Example fix
// before
QueryResponseRecord response = stagedQuery.execute(database);
if (response == null) {
throw new LSHException(database.getLastError().message);
}
// after (caller-side: retry on transient failure)
try {
service.querySimilarFunctions(query, listener, monitor);
} catch (LSHException e) {
if (isTransient(e.getMessage())) {
service.initializeDatabase(url); // reconnect
service.querySimilarFunctions(query, listener, monitor);
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate database is ready before querying
if (service.getDatabaseStatus() != Status.Ready) {
throw new IllegalStateException(
"BSim database not ready: " + service.getDatabaseStatus());
} Try / catch
try {
service.querySimilarFunctions(query, listener, monitor);
} catch (LSHException e) {
FunctionDatabase.BSimError lastErr = service.getLastError();
String detail = (lastErr != null) ? lastErr.message : e.getMessage();
if (isTransientDatabaseError(detail)) {
service.initializeDatabase(originalUrl); // reconnect and retry
service.querySimilarFunctions(query, listener, monitor);
} else {
throw e;
}
} Prevention
- Always check getDatabaseStatus() == Status.Ready before issuing queries.
- For long multi-stage queries, implement checkpointing so partial results survive a mid-query failure.
- Keep the BSim server URL and connection parameters stable during a query session to avoid mid-flight reconnection issues.
- Log service.getLastError() immediately after any query exception to capture the root database error.
When it happens
Trigger: Occurs during executeStagedQuery() when stagedQuery.execute(database) returns null for any staged chunk of a similar-function query. Common triggers include a PostgreSQL/elastic/H2 BSim server going down mid-query, authentication session expiry during a long multi-stage query, a malformed query object that the database rejects, or the database encountering an internal error (e.g., connection dropped, SQL error) that sets lastError without throwing.
Common situations: Running a large BSim similarity search against a remote server over an unstable network. Querying a BSim database that was simultaneously dropped or restarted by another process. Using a database whose schema/layout version is incompatible with the client. Hitting a server-side timeout during a staged query with many functions.
Related errors
- Database does not exist
- Password entry was cancelled
- Could not create database:
- Optional table: column type mismatch
- Could not resolve filter specifying executable:
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/54d3d5986308b0df.
Report an issue: GitHub.