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

  1. Load the correct data type archive (File > Configure/parse headers, or attach a .gdt) so the named type exists, then re-run.
  2. 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'.
  3. Create the missing type in the Data Type Manager before invoking the tool so dtm.getDataType("/" + typeName) succeeds.
  4. 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

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)