NationalSecurityAgency/ghidra · error · SQLException
Bad exetable rowid
Error message
Bad exetable rowid
What it means
Thrown by ExeTable.querySingleExecutableId when a SELECT by id returns no rows (rs.next() is false). The requested exetable row id does not exist. This is the read-side analog of error 808: a lookup for an executable that is not present.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/tables/ExeTable.java:317
}
return count;
}
/**
* Query for a single executable based on its exetable -id-
*
* @param id the exetable id
* @return the executable row
* @throws SQLException if there is a problem creating or executing the query
*/
public ExecutableRow querySingleExecutableId(long id) throws SQLException {
PreparedStatement s =
selectByIdStatement.prepareIfNeeded(() -> db.prepareStatement(SELECT_BY_ID_STMT));
s.setInt(1, (int) id);
try (ResultSet rs = s.executeQuery()) {
if (!rs.next()) {
throw new SQLException("Bad exetable rowid");
}
ExecutableRow row = new ExecutableRow();
extractExecutableRow(rs, row);
return row;
}
}
/**
* Return the executable with matching md5 (if any)
*
* @param md5 the md5 hash to query
* @return the ExecutableRow data or null
* @throws SQLException if there is a problem creating or executing the query
*/
public ExecutableRow queryMd5ExeMatch(String md5) throws SQLException {
PreparedStatement s =
selectByMd5Statement.prepareIfNeeded(() -> db.prepareStatement(SELECT_BY_MD5_STMT));View on GitHub (pinned to d5f144c24d)
Solutions
- Confirm the id was obtained from the same live database.
- Use a broader query (e.g., by md5) to locate the executable if the id is uncertain.
- Guard long ids against int overflow before calling (id must fit in 32-bit signed range).
- Recover or rebuild the database if rows are missing due to corruption.
Example fix
// before
ExecutableRow row = table.querySingleExecutableId(id);
// after
if (id > Integer.MAX_VALUE || id < Integer.MIN_VALUE) {
throw new IllegalArgumentException("exe id out of int range: " + id);
}
ExecutableRow row = table.querySingleExecutableId(id); Defensive patterns
Strategy: validation
Validate before calling
// Guard long ids against int truncation and absence before lookup.
if (id < Integer.MIN_VALUE || id > Integer.MAX_VALUE) {
throw new IllegalArgumentException("exe id out of int range: " + id);
}
// Optionally check existence first via a count query. Try / catch
try {
return exeTable.querySingleExecutableId(id);
} catch (SQLException e) {
if (e.getMessage().contains("Bad exetable rowid")) {
return exeTable.queryExecutableMd5(md5); // fallback lookup
}
throw e;
} Prevention
- Use ids only from the same live database.
- Validate id range fits a 32-bit signed int (the internal setInt cast).
- Fall back to md5-based lookup when id validity is uncertain.
When it happens
Trigger: Calling querySingleExecutableId(id) with an id not present in exetable. The executable was deleted, the id is foreign, or the database is missing the row. The internal setInt(1, (int) id) cast means a long id outside int range truncates and will not match.
Common situations: Looking up an executable by a stale or cross-database id. Querying after a deletion. Int-truncation of large ids. Partial database restore missing exetable rows.
Related errors
- No desctable rows matching id
- Could not delete executable record
- Id is not present in string table: {name}
- SQL database does not have callgraph information enabled
- Did not get desctable sequence number after insertion
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/3d73a412f742fcad.
Report an issue: GitHub.