LaurieWired/GhidraMCP · warning
Base type not found for " + typeName + ", defaulting to void
Error message
Base type not found for " + typeName + ", defaulting to void*
What it means
This is not a thrown exception but a warning logged via Msg.warn inside GhidraMCPPlugin's type-parsing helper. When a type name like 'Foo*' requires a base type, the plugin looks up the base type with findDataTypeByNameInAllCategories; if the lookup fails, it logs this warning and silently substitutes a void* pointer instead of failing the operation. It exists so struct/pointer parsing from decompiler output never hard-fails, at the cost of producing a possibly wrong type.
Solutions
- Define or import the missing base type into the program's Data Type Manager (or attach the GDT archive containing it) before re-running the tool, so findDataTypeByNameInAllCategories resolves it.
- Verify the exact type name spelling/case; the lookup is by name across categories, so a mismatched or qualified name ('myLib::Foo' vs 'Foo') will miss — create the type under a category the search covers.
- If the base type genuinely cannot be provided, accept the void* fallback and retype members manually in the resulting structure.
- Extend findDataTypeByNameInAllCategories or the parsing code to also check built-in/arch default type catalogs before falling back.
Example fix
// before
DataType baseType = findDataTypeByNameInAllCategories(dtm, baseTypeName);
if (baseType != null) {
return new PointerDataType(baseType);
}
Msg.warn(this, "Base type not found for " + typeName + ", defaulting to void*");
return new PointerDataType(dtm.getDataType("/void"));
// after
DataType baseType = findDataTypeByNameInAllCategories(dtm, baseTypeName);
if (baseType == null) {
baseType = dtm.getDataType("/" + baseTypeName); // direct root-path lookup
}
if (baseType != null) {
return new PointerDataType(baseType);
}
Msg.warn(this, "Base type not found for " + typeName + ", defaulting to void*");
return new PointerDataType(dtm.getDataType("/void")); Defensive patterns
Strategy: validation
Validate before calling
// Ghidra scripting / client-side pre-check before invoking the MCP tool
Transaction tx = null;
try {
DataType dt = currentProgram.getDataTypeManager().getDataType("/MyStruct");
if (dt == null) {
throw new IllegalStateException(
"Base type 'MyStruct' is not in the Data Type Manager; " +
"define it or load the containing .gdt archive first.");
}
// safe to call the tool now
} finally {
if (tx != null) end;
} Type guard
function hasBaseType(program, baseTypeName) {
return program.getDataTypeManager().getAllDataTypes().stream()
.anyMatch(dt -> dt.getName().equals(baseTypeName));
} Prevention
- Define or import every struct type referenced by pointer types before running MCP struct-generation tools.
- Keep a .gdt archive with the binary's known types loaded into each project.
- Match type-name spelling and category placement exactly as the lookup expects.
- Watch the Ghidra log for 'Base type not found' warnings; treat them as a signal that output structures contain void* placeholders.
When it happens
Trigger: Calling any plugin endpoint that parses a type string (e.g. decompiler or struct-related HTTP endpoints) where the string contains a pointer type 'BaseType*' (or the type appears in the pointer-parsing branch) and 'BaseType' cannot be resolved by findDataTypeByNameInAllCategories in the program's data type manager — e.g. the struct is defined only in the decompiler output but was never imported into the program.
Common situations: Analyzing binaries where the decompiler emits pointers to types that don't exist in the Ghidra data type manager (custom structs, types from a missing/incompatible GDT archive, or a typo in a user-supplied type name passed to an MCP tool); users then see structures generated with void* members instead of the expected typed pointers.
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/c46ed12184d589d9.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/com/lauriewired/GhidraMCPPlugin.java:1445
return dataType;
}
// Check for Windows-style pointer types (PXXX)
if (typeName.startsWith("P") && typeName.length() > 1) {
String baseTypeName = typeName.substring(1);
// Special case for PVOID
if (baseTypeName.equals("VOID")) {
return new PointerDataType(dtm.getDataType("/void"));
}
// Try to find the base type
DataType baseType = findDataTypeByNameInAllCategories(dtm, baseTypeName);
if (baseType != null) {
return new PointerDataType(baseType);
}
Msg.warn(this, "Base type not found for " + typeName + ", defaulting to void*");
return new PointerDataType(dtm.getDataType("/void"));
}
// Handle common built-in types
switch (typeName.toLowerCase()) {
case "int":
case "long":
return dtm.getDataType("/int");
case "uint":
case "unsigned int":
case "unsigned long":
case "dword":
return dtm.getDataType("/uint");
case "short":
return dtm.getDataType("/short");
case "ushort":
case "unsigned short":
case "word":View on GitHub (pinned to 27f316f801)