NationalSecurityAgency/ghidra · error · SQLException
ExecutableRecord does not have id
Error message
ExecutableRecord does not have id
What it means
Thrown by ExeToCategoryTable.queryExecutableCategories when the exeid parameter is 0, which the code treats as 'no id'. An ExecutableRecord with a zero/null-equivalent id has not been persisted to the database, so querying its categories is invalid. Category lookups require a real exetable row id.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/tables/ExeToCategoryTable.java:141
String type = catstringtable.getString(row.id_type);
String category = catstringtable.getString(row.id_category);
CategoryRecord catrec = new CategoryRecord(type, category);
vecres.add(catrec);
}
}
/**
*
* @param exeid the executable table id
* @param max the max number of records to return
* @return the list of category records
* @throws SQLException if there is a problem creating or executing the query
*/
public List<CategoryRecord> queryExecutableCategories(long exeid, int max)
throws SQLException {
if (exeid == 0) {
throw new SQLException("ExecutableRecord does not have id");
}
PreparedStatement s =
selectCategoriesStatement.prepareIfNeeded(() -> db.prepareStatement(SELECT_STMT));
s.setInt(1, (int) exeid);
try (ResultSet rs = s.executeQuery()) {
List<CategoryRecord> catvec = new ArrayList<CategoryRecord>();
extractCategoryRecords(rs, catvec, max);
return catvec;
}
}
/**
*
* @param erec the executable record
* @throws SQLException if there is a problem inserting the category
*/
public void storeExecutableCategories(ExecutableRecord erec) throws SQLException {View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure the ExecutableRecord has been inserted and assigned a non-zero row id before querying categories.
- Validate exeid != 0 upstream and throw a clearer error or skip.
- After insert, confirm the returned/generated id is set on the record object.
- Trace the insert path to verify id assignment (related to errors 811/807).
Example fix
// before
List<CategoryRecord> cats = table.queryExecutableCategories(exeRec.getRowId(), max); // id==0
// after
long exeid = exeRec.getRowId();
if (exeid == 0) {
throw new IllegalStateException("ExecutableRecord not persisted; row id is 0");
}
List<CategoryRecord> cats = table.queryExecutableCategories(exeid, max); Defensive patterns
Strategy: validation
Validate before calling
// Validate the executable id is set before category lookup.
long exeid = exeRec.getRowId();
if (exeid == 0) {
throw new IllegalStateException("ExecutableRecord not persisted (id==0)");
}
return table.queryExecutableCategories(exeid, max); Prevention
- Always persist an ExecutableRecord before querying its categories.
- After insert, confirm the row id is assigned to the record.
- Treat an id of 0 as 'unset' and validate against it.
When it happens
Trigger: Calling queryExecutableCategories(0, max) — passing an exeid of 0. Happens when an ExecutableRecord's row id was never assigned (still 0/unset) and the caller forwards it directly. The guard uses 0 (not null) because the parameter is a primitive long.
Common situations: Using a freshly constructed ExecutableRecord that has not been inserted (id defaults to 0). Forgetting to persist the executable before querying its categories. Reading an id field that was never populated after insert (insert path failed to set it).
Related errors
- Missing databaseName for drop database
- drop database name must match
- SQL database does not have callgraph information enabled
- FunctionDescription does not have id
- No desctable rows matching id
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/82708487459877a8.
Report an issue: GitHub.