NationalSecurityAgency/ghidra · error · ValueError

Could not evaluate '{expr}' or convert result '{value}'

Error message

Could not evaluate '{expr}' or convert result '{value}'

What it means

Raised as ValueError at the end of the DbgEng expression evaluator when Evaluate() succeeded (check_err passed) but the returned DEBUG_VALUE type did not match any known branch (INT8/16/32/64, FLOAT32/64/80/82/128). In practice this is a defensive/unreachable branch: it guards against an unexpected value-type enum from DbgEng.

Source

Thrown at Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/util.py:645

    if type == DbgEng.DEBUG_VALUE_INT8:
        return value.u.I8
    if type == DbgEng.DEBUG_VALUE_INT16:
        return value.u.I16
    if type == DbgEng.DEBUG_VALUE_INT32:
        return value.u.I32
    if type == DbgEng.DEBUG_VALUE_INT64:
        return value.u.I64.I64
    if type == DbgEng.DEBUG_VALUE_FLOAT32:
        return value.u.F32
    if type == DbgEng.DEBUG_VALUE_FLOAT64:
        return value.u.F64
    if type == DbgEng.DEBUG_VALUE_FLOAT80:
        return value.u.F80Bytes
    if type == DbgEng.DEBUG_VALUE_FLOAT82:
        return value.u.F82Bytes
    if type == DbgEng.DEBUG_VALUE_FLOAT128:
        return value.u.F128Bytes
    raise ValueError(
        f"Could not evaluate '{expr}' or convert result '{value}'")


@dbg.eng_thread
def get_pc() -> int:
    return dbg._base.reg.get_pc()


@dbg.eng_thread
def get_sp() -> int:
    return dbg._base.reg.get_sp()


@dbg.eng_thread
def GetProcessIdsByIndex(count: int = 0) -> Tuple[List[int], List[int]]:
    # TODO: This could be contributed upstream?
    if count == 0:
        try:

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Restrict the DesiredType argument to one of the handled DEBUG_VALUE_* constants (default INT64 covers most cases).
  2. If a new value type appears, extend the if-chain in the evaluator to handle it.
  3. Catch ValueError and report the unhandled type/value so the gap can be patched upstream.

Example fix

// before
return evaluate(expr, type=some_custom_type)  # unhandled -> ValueError
// after
handled = {DbgEng.DEBUG_VALUE_INT8, DbgEng.DEBUG_VALUE_INT16,
            DbgEng.DEBUG_VALUE_INT32, DbgEng.DEBUG_VALUE_INT64,
            DbgEng.DEBUG_VALUE_FLOAT32, DbgEng.DEBUG_VALUE_FLOAT64,
            DbgEng.DEBUG_VALUE_FLOAT80, DbgEng.DEBUG_VALUE_FLOAT82,
            DbgEng.DEBUG_VALUE_FLOAT128}
assert type in handled, f"unsupported DesiredType {type}"
return evaluate(expr, type=type)
Defensive patterns

Strategy: try-catch

Validate before calling

handled = {DbgEng.DEBUG_VALUE_INT8, DbgEng.DEBUG_VALUE_INT16,
           DbgEng.DEBUG_VALUE_INT32, DbgEng.DEBUG_VALUE_INT64,
           DbgEng.DEBUG_VALUE_FLOAT32, DbgEng.DEBUG_VALUE_FLOAT64,
           DbgEng.DEBUG_VALUE_FLOAT80, DbgEng.DEBUG_VALUE_FLOAT82,
           DbgEng.DEBUG_VALUE_FLOAT128}
assert type in handled, f'unhandled DesiredType {type}'

Type guard

def is_handled_value_type(t) -> bool:
    return t in {DbgEng.DEBUG_VALUE_INT8, DbgEng.DEBUG_VALUE_INT16,
                DbgEng.DEBUG_VALUE_INT32, DbgEng.DEBUG_VALUE_INT64,
                DbgEng.DEBUG_VALUE_FLOAT32, DbgEng.DEBUG_VALUE_FLOAT64,
                DbgEng.DEBUG_VALUE_FLOAT80, DbgEng.DEBUG_VALUE_FLOAT82,
                DbgEng.DEBUG_VALUE_FLOAT128}

Try / catch

try:
    val = evaluate(expr, type=desired)
except ValueError as e:
    log.warning('evaluator cannot handle type %s for %r: %s', desired, expr, e)
    val = evaluate(expr, type=DbgEng.DEBUG_VALUE_INT64)  # safe fallback

Prevention

When it happens

Trigger: Calling the evaluator (util expr evaluation) with a DesiredType constant outside the handled set, or a DbgEng version that returns a value type enum the agent does not enumerate.

Common situations: Passing a custom DEBUG_VALUE_* constant; newer DbgEng exposing additional value types (e.g. vector) not yet handled by the agent.

Related errors


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