NationalSecurityAgency/ghidra · error · TypeError
{object} is not {err_msg}
Error message
{object} is not {err_msg} What it means
Raised by find_pid_by_pattern() in exdi_methods.py:34 when a TraceObject's path does not match the expected Exdi session/process pattern. This is a type/shape guard: it ensures the object passed to an Exdi-scoped method actually represents an Exdi threads/processes container before extracting the procnum capture group. The error message is filled by the caller's err_msg (e.g. 'an ExdiThreadsContainer').
Source
Thrown at Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/exdi/exdi_methods.py:34
import re
from ghidratrace import sch
from ghidratrace.client import (MethodRegistry, ParamDesc, Address,
AddressRange, TraceObject)
from ghidradbg import util, commands, methods
from ghidradbg.methods import REGISTRY, SESSIONS_PATTERN, SESSION_PATTERN, extre
from . import exdi_commands
XPROCESSES_PATTERN = extre(SESSION_PATTERN, '\\.ExdiProcesses')
XPROCESS_PATTERN = extre(XPROCESSES_PATTERN, '\\[(?P<procnum>\\d*)\\]')
XTHREADS_PATTERN = extre(XPROCESS_PATTERN, '\\.Threads')
def find_pid_by_pattern(pattern, object, err_msg):
mat = pattern.fullmatch(object.path)
if mat is None:
raise TypeError(f"{object} is not {err_msg}")
pid = int(mat['procnum'])
return pid
def find_pid_by_obj(object):
return find_pid_by_pattern(XTHREADS_PATTERN, object, "an ExdiThreadsContainer")
class ExdiProcessContainer(TraceObject):
pass
class ExdiThreadContainer(TraceObject):
pass
@REGISTRY.method(action='refresh', display="Refresh Target Processes")
def refresh_exdi_processes(node: ExdiProcessContainer) -> None:View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure Exdi is the active debug transport (util.is_exdi() true) before invoking Exdi-scoped methods.
- Pass an object whose path matches the ExdiProcesses/ExdiThreads schema (e.g. 'Sessions[1].ExdiProcesses[0].Threads').
- Switch to the non-Exdi equivalent method if you are in a native dbgeng session.
Example fix
// before # in a native dbgeng session, calling an Exdi helper: find_pid_by_obj(process_obj) # TypeError: ... is not an ExdiThreadsContainer // after # use the native helper instead: find_proc_by_obj(process_obj)
Defensive patterns
Strategy: type-guard
Validate before calling
import re
from ghidradbg.exdi.exdi_methods import XTHREADS_PATTERN
def is_exdi_threads_obj(obj) -> bool:
return XTHREADS_PATTERN.fullmatch(obj.path) is not None
if not is_exdi_threads_obj(obj):
raise ValueError('expected an ExdiThreadsContainer object') Type guard
def is_exdi_threads_obj(obj) -> bool:
from ghidradbg.exdi.exdi_methods import XTHREADS_PATTERN
return bool(getattr(obj, 'path', None)) and XTHREADS_PATTERN.fullmatch(obj.path) is not None Try / catch
try:
pid = find_pid_by_obj(obj)
except TypeError as e:
if 'is not' in str(e):
raise ValueError(f'wrong object type for Exdi pid lookup: {obj}') from e
raise Prevention
- Only call Exdi helpers when util.is_exdi() is true.
- Resolve objects from the ExdiProcesses/ExdiThreads subtrees.
- Keep Exdi and native dbgeng dispatch paths separate.
When it happens
Trigger: Passing a non-Exdi TraceObject (e.g. a normal Process or Thread object) to an Exdi-specific method that calls find_pid_by_obj/find_pid_by_pattern; path shape changed due to a schema mismatch; using Exdi methods when Exdi is not the active transport.
Common situations: Mixing the regular dbgeng method routing with the Exdi method routing; schema version drift where path prefixes differ; calling Exdi helpers from a non-Exdi (native dbgeng) session.
Related errors
- {object} is not {err_msg}
- {object} is not a Module
- Unsupported value: {}
- Invalid value for {}
- No such address space: %s
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/84e69babf137d04c.
Report an issue: GitHub.