NationalSecurityAgency/ghidra · error · TypeError

{object} is not a Module

Error message

{object} is not a Module

What it means

Thrown by find_module_name_by_mod_obj in the Ghidra GDB agent when a TraceObject's path does not fullmatch MODULE_PATTERN (Inferiors[<infnum>].Modules[<modname>]). The agent uses regex matching to derive the module name from the object's path; a non-module object (e.g. a Modules container, a Memory region, or a mistyped/synthetic path) yields no match. It is raised as TypeError because the caller passed an object of the wrong shape.

Source

Thrown at Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/methods.py:146

    return find_inf_by_pattern(object, THREADS_PATTERN, "a ThreadContainer")


def find_inf_by_mem_obj(object: TraceObject) -> gdb.Inferior:
    return find_inf_by_pattern(object, MEMORY_PATTERN, "a Memory")


def find_inf_by_modules_obj(object: TraceObject) -> gdb.Inferior:
    return find_inf_by_pattern(object, MODULES_PATTERN, "a ModuleContainer")


def find_inf_by_mod_obj(object: TraceObject) -> gdb.Inferior:
    return find_inf_by_pattern(object, MODULE_PATTERN, "a Module")


def find_module_name_by_mod_obj(object: TraceObject) -> str:
    mat = MODULE_PATTERN.fullmatch(object.path)
    if mat is None:
        raise TypeError(f"{object} is not a Module")
    return mat['modname']


def find_thread_by_num(inf: gdb.Inferior, tnum: int) -> gdb.InferiorThread:
    for t in inf.threads():
        if t.num == tnum:
            return t
    raise KeyError(f"Inferiors[{inf.num}].Threads[{tnum}] does not exist")


def find_thread_by_pattern(pattern: re.Pattern, object: TraceObject,
                           err_msg: str) -> gdb.InferiorThread:
    mat = pattern.fullmatch(object.path)
    if mat is None:
        raise TypeError(f"{object} is not {err_msg}")
    infnum = int(mat['infnum'])
    tnum = int(mat['tnum'])
    inf = find_inf_by_num(infnum)

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Confirm the object's .path is a descendant of Inferiors[N].Modules and contains a [modname] key segment before extracting the name.
  2. Gate the call: use a kind/path predicate (or find_inf_by_mod_obj success) before find_module_name_by_mod_obj so wrong-kind objects never reach it.
  3. Inspect the live TraceObject path at the call site (log object.path) and compare against re.compile pattern MODULE_PATTERN to find the mismatch.
  4. Ensure the trace object was created via the canonical module-insertion code path that emits Inferiors[N].Modules[<modpath>].

Example fix

// before
name = find_module_name_by_mod_obj(obj)
// after
if MODULE_PATTERN.fullmatch(obj.path) is None:
    raise ValueError(f"expected a Module object, got {obj.path}")
name = find_module_name_by_mod_obj(obj)
Defensive patterns

Strategy: type-guard

Validate before calling

import re
# MODULE_PATTERN imported from ghidragdb.methods
_IS_MODULE = lambda obj: MODULE_PATTERN.fullmatch(obj.path) is not None
if not _IS_MODULE(obj):
    raise ValueError(f"expected Module object, got {obj.path}")
name = find_module_name_by_mod_obj(obj)

Type guard

def is_module_obj(obj: TraceObject) -> bool:
    return MODULE_PATTERN.fullmatch(obj.path) is not None

Try / catch

try:
    name = find_module_name_by_mod_obj(obj)
except TypeError:
    # wrong kind of object; refresh schema binding / log obj.path
    log.warning("not a Module object: %s", obj.path)
    raise

Prevention

When it happens

Trigger: Calling find_module_name_by_mod_obj with a TraceObject whose .path is anything other than Inferiors[N].Modules[name] — e.g. an Inferiors[N].Modules container, an Inferiors[N] inferior, or a Modules entry created by a code path that did not normalize the path. Typically reached via a method handler that receives a target object from Ghidra and extracts the module name without first validating kind.

Common situations: A trace-rpc method bound to a Module schema node receives a sibling object (container or section) because the object was created/inserted at the wrong path; partial trace population where Modules children exist but with malformed keys; cross-version schema drift where MODULE_PATTERN changed but stale objects remain in the trace.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/4afb5f8ffba33da9. Report an issue: GitHub.