LaurieWired/GhidraMCP · warning
Unknown type: " + typeName + ", defaulting to int
Error message
Unknown type: " + typeName + ", defaulting to int
What it means
A warning (not an exception) logged in the built-in-type fallback branch of GhidraMCPPlugin's type-string parser. After the pointer/array handling and a direct root-path lookup via dtm.getDataType("/" + typeName) both fail, the parser logs 'Unknown type' and returns the '/int' data type as a silent default. It signals that a type name supplied to (or emitted by) a tool could not be resolved in the program's data type manager.
Solutions
- Load the correct data type archive (File > Configure/parse headers, or attach a .gdt) so the named type exists, then re-run.
- Use the exact built-in names the parser's switch recognizes (e.g. 'int', 'char', 'void', 'unsigned int' lowercased) instead of platform typedefs like 'DWORD' or 'uint32'.
- Create the missing type in the Data Type Manager before invoking the tool so dtm.getDataType("/" + typeName) succeeds.
- Patch the parser to map common typedefs (uint32->int, DWORD->int) instead of blind int fallback if you control the plugin code.
Example fix
// before
DataType directType = dtm.getDataType("/" + typeName);
if (directType != null) {
return directType;
}
Msg.warn(this, "Unknown type: " + typeName + ", defaulting to int");
return dtm.getDataType("/int");
// after
DataType directType = dtm.getDataType("/" + typeName);
if (directType != null) {
return directType;
}
DataType aliased = resolveTypedef(typeName); // map uint32/DWORD/etc. to built-ins
if (aliased != null) {
return aliased;
}
Msg.warn(this, "Unknown type: " + typeName + ", defaulting to int");
return dtm.getDataType("/int"); Defensive patterns
Strategy: validation
Validate before calling
// Client-side check before sending a type name to the plugin
Set<String> builtins = Set.of("int", "char", "void", "unsigned int", "long",
"short", "float", "double", "unsigned char", "unsigned long", "unsigned short");
boolean known = builtins.contains(typeName.toLowerCase())
|| currentProgram.getDataTypeManager().getDataType("/" + typeName) != null;
if (!known) {
throw new IllegalArgumentException("Type '" + typeName + "' is not a built-in and "
+ "does not exist in the Data Type Manager; define or import it first.");
} Type guard
function isResolvableType(program, typeName) {
const dtm = program.getDataTypeManager();
return BUILTIN_NAMES.includes(typeName.toLowerCase())
|| dtm.getDataType('/' + typeName) !== null;
} Prevention
- Only pass type names that exist in the program's Data Type Manager or the parser's built-in switch (lowercase C keywords).
- Load standard header/GDT archives (windows, posix) before analysis so common typedefs resolve.
- Prefer canonical Ghidra type names ('unsigned int') over platform typedefs ('DWORD', 'uint32').
- After tool calls, inspect generated structures for unexpected int fields — they indicate this fallback fired.
When it happens
Trigger: Calling a plugin endpoint that accepts a type-name string (e.g. create-struct or apply-type tooling) with a name that is neither a recognized built-in keyword in the parser's switch nor an existing data type at the DTM root path ('/' + typeName). Typical inputs: 'uint32', 'DWORD', 'LPSTR', or a struct name that was never defined in this program.
Common situations: Users pass Windows/SDK type names or language typedefs that Ghidra does not define by default; programs analyzed without the appropriate GDT archives loaded; scripts/tools receiving types from decompiler output of an uninitialized header set — resulting fields are silently typed as int.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of LaurieWired/GhidraMCP@27f316f801 (2026-09-10).
Data as JSON: /api/errors/b963bdaa41359c93.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/com/lauriewired/GhidraMCPPlugin.java:1490
case "__int64":
return dtm.getDataType("/longlong");
case "ulonglong":
case "unsigned __int64":
return dtm.getDataType("/ulonglong");
case "bool":
case "boolean":
return dtm.getDataType("/bool");
case "void":
return dtm.getDataType("/void");
default:
// Try as a direct path
DataType directType = dtm.getDataType("/" + typeName);
if (directType != null) {
return directType;
}
// Fallback to int if we couldn't find it
Msg.warn(this, "Unknown type: " + typeName + ", defaulting to int");
return dtm.getDataType("/int");
}
}
/**
* Find a data type by name in all categories/folders of the data type manager
* This searches through all categories rather than just the root
*/
private DataType findDataTypeByNameInAllCategories(DataTypeManager dtm, String typeName) {
// Try exact match first
DataType result = searchByNameInAllCategories(dtm, typeName);
if (result != null) {
return result;
}
// Try lowercase
return searchByNameInAllCategories(dtm, typeName.toLowerCase());
}View on GitHub (pinned to 27f316f801)