NationalSecurityAgency/ghidra · error · IllegalArgumentException
Cannot find column '{}' for @DBAnnotatedColumn on {}
Error message
Cannot find column '{}' for @DBAnnotatedColumn on {} What it means
@DBAnnotatedColumn(value="x") must name a column that is also declared by a matching @DBAnnotatedField(column="x"). writeColumnNumbers builds a name->number map from the collected fields, then looks up the handle's declared name; a miss means the handle points at a column that was never registered in the schema, so IllegalArgumentException is thrown.
Source
Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/DBCachedObjectStoreFactory.java:1186
continue;
}
int mod = f.getModifiers();
if (!Modifier.isStatic(mod)) {
throw new IllegalArgumentException(
"@" + DBAnnotatedColumn.class.getSimpleName() +
" fields must be static. Got " + f);
}
if (f.getType() != DBObjectColumn.class) {
throw new IllegalArgumentException(
"@" + DBAnnotatedColumn.class.getSimpleName() + " fields must be " +
DBObjectColumn.class.getSimpleName() + " type. Got " + f);
}
String name = annotation.value();
Integer columnNumber = numbersByName.get(name);
if (columnNumber == null) {
throw new IllegalArgumentException("Cannot find column '" + name + "' for @" +
DBAnnotatedColumn.class.getSimpleName() + " on " + f);
}
f.setAccessible(true);
try {
DBObjectColumn already = (DBObjectColumn) f.get(null);
if (already == null) {
f.set(null, DBObjectColumn.get(columnNumber.intValue()));
}
else if (already.columnNumber != columnNumber.intValue()) {
throw new AssertionError();
}
}
catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
}View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure a @DBAnnotatedField(column="x") exists whose column() exactly matches the @DBAnnotatedColumn("x") value (case-sensitive).
- Grep the type for the column name to spot the typo/mismatch.
- If migrating schema, verify @DBAnnotatedObjectInfo version and that the column layout still declares that name.
Example fix
// before
@DBAnnotatedColumn("fullname")
static DBObjectColumn NAME;
@DBAnnotatedField(column="name")
String name;
// after
@DBAnnotatedColumn("name")
static DBObjectColumn NAME;
@DBAnnotatedField(column="name")
String name; Defensive patterns
Strategy: validation
Validate before calling
// Collect column names from @DBAnnotatedField, then verify each @DBAnnotatedColumn name matches.
Set<String> valueCols = new HashSet<>();
for (Field f : objectType.getDeclaredFields()) {
DBAnnotatedField a = f.getAnnotation(DBAnnotatedField.class);
if (a != None) valueCols.add(a.column());
}
for (Field f : objectType.getDeclaredFields()) {
DBAnnotatedColumn c = f.getAnnotation(DBAnnotatedColumn.class);
if (c != None && !valueCols.contains(c.value())) {
throw new IllegalStateException("@DBAnnotatedColumn references unknown column: " + c.value());
}
} Prevention
- Derive the @DBAnnotatedColumn value and the matching @DBAnnotatedField column() from a single shared constant to avoid drift.
- Add a schema-integrity test that pairs every handle name to a declared field column.
When it happens
Trigger: `numbersByName.get(annotation.value()) == None`. Happens when the @DBAnnotatedColumn value has no matching @DBAnnotatedField with the same column name - a typo, case mismatch, renamed column, or a handle for a column removed in the current schema version.
Common situations: Renaming a @DBAnnotatedField's column without updating the @DBAnnotatedColumn handle; renaming a constant; declaring a handle for a column that only exists in another schema version; case differences in the column name string.
Related errors
- DBAnnotatedObject {objectType} must have @DBAnnotatedObjectI
- @DBAnnotatedColumn fields must be static. Got {}
- The parameter '%s' of method '%s' refers to a non-existent s
- {}
- Column {} is not indexed
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/c1f1296620edd7c2.
Report an issue: GitHub.