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
- Confirm the object's .path is a descendant of Inferiors[N].Modules and contains a [modname] key segment before extracting the name.
- 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.
- Inspect the live TraceObject path at the call site (log object.path) and compare against re.compile pattern MODULE_PATTERN to find the mismatch.
- 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
- always route objects through the typed find_*_by_obj wrappers
- validate object.path against the expected pattern at dispatch boundaries
- keep schema node bindings in sync with resolver patterns
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
- Inferiors[{inf.num}].Threads[{tnum}] does not exist
- Inferiors[{thread.inferior.num}].Threads[{thread.num}].Stack
- No such register: {name}
- Breakpoints[{breaknum}] does not exist
- {object} is not {err_msg}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/4afb5f8ffba33da9.
Report an issue: GitHub.