NationalSecurityAgency/ghidra · error · KeyError

Events[{excnum}] does not exist

Error message

Events[{excnum}] does not exist

What it means

Raised as KeyError by find_exc_by_number() when util.GetExceptionFilterParameters() fails with E_NOINTERFACE_Error, meaning the exception filter at that index is not registered with the DbgEng engine. Note the message textually says 'Events' although it concerns exception filters — a copy/paste quirk in the agent.

Source

Thrown at Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py:229

        raise TypeError(f"{object} is not {err_msg}")
    eventnum = int(mat['eventnum'])
    return (eventnum, find_evt_by_number(eventnum))


def find_evt_cont_by_obj(object: TraceObject) -> DbgEng._DEBUG_SPECIFIC_FILTER_PARAMETERS:
    return find_evt_by_pattern(PROC_EVENT_CONT_PATTERN, object, "as Event")


def find_evt_exec_by_obj(object: TraceObject) -> DbgEng._DEBUG_SPECIFIC_FILTER_PARAMETERS:
    return find_evt_by_pattern(PROC_EVENT_EXEC_PATTERN, object, "as Event")


def find_exc_by_number(excnum: int) -> DbgEng._DEBUG_EXCEPTION_FILTER_PARAMETERS:
    try:
        (n_events, n_spec_exc, n_arb_exc) = util.GetNumberEventFilters()
        return util.GetExceptionFilterParameters(n_events + excnum, None, 1)
    except exception.E_NOINTERFACE_Error:
        raise KeyError(f"Events[{excnum}] does not exist")


def find_exc_by_pattern(pattern: re.Pattern, object: TraceObject,
                        err_msg: str) -> DbgEng._DEBUG_EXCEPTION_FILTER_PARAMETERS:
    mat = pattern.fullmatch(object.path)
    if mat is None:
        raise TypeError(f"{object} is not {err_msg}")
    excnum = int(mat['excnum'])
    return (excnum, find_exc_by_number(excnum))


def find_exc_cont_by_obj(object: TraceObject) -> DbgEng._DEBUG_SPECIFIC_FILTER_PARAMETERS:
    return find_exc_by_pattern(PROC_EXCEPTION_CONT_PATTERN, object, "as Exception")


def find_exc_exec_by_obj(object: TraceObject) -> DbgEng._DEBUG_SPECIFIC_FILTER_PARAMETERS:
    return find_exc_by_pattern(PROC_EXCEPTION_EXEC_PATTERN, object, "as Exception")

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Call util.GetNumberEventFilters() first and verify excnum is within [0, n_spec_exc) before calling find_exc_by_number().
  2. Re-refresh the trace's exception list so the captured excnum reflects the current engine state.
  3. Catch KeyError and surface a user-facing 'exception filter does not exist' message with the offending excnum.

Example fix

// before
params = find_exc_by_number(excnum)
// after
n_events, n_spec_exc, _ = util.GetNumberEventFilters()
if not (0 <= excnum < n_spec_exc):
    raise KeyError(f"Exception filter [{excnum}] out of range (have {n_spec_exc})")
params = find_exc_by_number(excnum)
Defensive patterns

Strategy: validation

Validate before calling

n_events, n_spec_exc, _ = util.GetNumberEventFilters()
if not (0 <= excnum < n_spec_exc):
    raise KeyError(f'Exception filter [{excnum}] out of range (have {n_spec_exc})')
params = find_exc_by_number(excnum)

Type guard

null

Try / catch

try:
    params = find_exc_by_number(excnum)
except KeyError:
    # refresh filter list and re-derive excnum from the current schema
    refresh_exceptions()
    return None

Prevention

When it happens

Trigger: Looking up an exception filter by excnum where n_events+excnum is out of range or the filter was never installed; querying a filter index before the engine has enumerated filters (GetNumberEventFilters returned counts that exclude the requested excnum).

Common situations: Indexing exception filters with a stale excnum captured before a target reload; calling before the debug session has populated its exception-filter table; off-by-one against n_events when the engine reports fewer filters than expected.

Related errors


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