{"record":{"id":"c46ed12184d589d9","repo":"LaurieWired/GhidraMCP","slug":"base-type-not-found-for-typename-defaulti","errorCode":null,"errorMessage":"Base type not found for \" + typeName + \", defaulting to void*","messagePattern":"Base type not found for \" \\+ typeName \\+ \", defaulting to void\\*","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/java/com/lauriewired/GhidraMCPPlugin.java","lineNumber":1445,"sourceCode":"            return dataType;\n        }\n\n        // Check for Windows-style pointer types (PXXX)\n        if (typeName.startsWith(\"P\") && typeName.length() > 1) {\n            String baseTypeName = typeName.substring(1);\n\n            // Special case for PVOID\n            if (baseTypeName.equals(\"VOID\")) {\n                return new PointerDataType(dtm.getDataType(\"/void\"));\n            }\n\n            // Try to find the base type\n            DataType baseType = findDataTypeByNameInAllCategories(dtm, baseTypeName);\n            if (baseType != null) {\n                return new PointerDataType(baseType);\n            }\n\n            Msg.warn(this, \"Base type not found for \" + typeName + \", defaulting to void*\");\n            return new PointerDataType(dtm.getDataType(\"/void\"));\n        }\n\n        // Handle common built-in types\n        switch (typeName.toLowerCase()) {\n            case \"int\":\n            case \"long\":\n                return dtm.getDataType(\"/int\");\n            case \"uint\":\n            case \"unsigned int\":\n            case \"unsigned long\":\n            case \"dword\":\n                return dtm.getDataType(\"/uint\");\n            case \"short\":\n                return dtm.getDataType(\"/short\");\n            case \"ushort\":\n            case \"unsigned short\":\n            case \"word\":","sourceCodeStart":1427,"sourceCodeEnd":1463,"githubUrl":"https://github.com/LaurieWired/GhidraMCP/blob/27f316f80139e2d5dec882519a1bdf4aa46ac04c/src/main/java/com/lauriewired/GhidraMCPPlugin.java#L1427-L1463","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nDataType baseType = findDataTypeByNameInAllCategories(dtm, baseTypeName);\nif (baseType != null) {\n    return new PointerDataType(baseType);\n}\nMsg.warn(this, \"Base type not found for \" + typeName + \", defaulting to void*\");\nreturn new PointerDataType(dtm.getDataType(\"/void\"));\n// after\nDataType baseType = findDataTypeByNameInAllCategories(dtm, baseTypeName);\nif (baseType == null) {\n    baseType = dtm.getDataType(\"/\" + baseTypeName); // direct root-path lookup\n}\nif (baseType != null) {\n    return new PointerDataType(baseType);\n}\nMsg.warn(this, \"Base type not found for \" + typeName + \", defaulting to void*\");\nreturn new PointerDataType(dtm.getDataType(\"/void\"));","handlingStrategy":"validation","validationCode":"// Ghidra scripting / client-side pre-check before invoking the MCP tool\nTransaction tx = null;\ntry {\n    DataType dt = currentProgram.getDataTypeManager().getDataType(\"/MyStruct\");\n    if (dt == null) {\n        throw new IllegalStateException(\n            \"Base type 'MyStruct' is not in the Data Type Manager; \" +\n            \"define it or load the containing .gdt archive first.\");\n    }\n    // safe to call the tool now\n} finally {\n    if (tx != null) end;\n}","typeGuard":"function hasBaseType(program, baseTypeName) {\n    return program.getDataTypeManager().getAllDataTypes().stream()\n        .anyMatch(dt -> dt.getName().equals(baseTypeName));\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["ghidra","java","type-lookup","fallback","decompiler"],"backgroundTag":"resource-not-found","analyzedSha":"27f316f80139e2d5dec882519a1bdf4aa46ac04c","analyzedAt":"2026-09-10T10:08:33.079Z","contentChangedAt":"2026-09-10T10:08:33.079Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}