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

  1. Ensure Exdi is the active debug transport (util.is_exdi() true) before invoking Exdi-scoped methods.
  2. Pass an object whose path matches the ExdiProcesses/ExdiThreads schema (e.g. 'Sessions[1].ExdiProcesses[0].Threads').
  3. 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

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


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