NationalSecurityAgency/ghidra · error · ValueError

Could not read value: {}

Error message

Could not read value: {}

What it means

Raised by Client._read_value() when deserializing an incoming Value and the active oneof field name does not match any reader branch (bool/byte/.../int_arr/.../address/range/child_desc). It indicates a protobuf Value carrying a field the client does not know how to decode — a protocol/schema mismatch rather than bad user data.

Source

Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py:930

        if name == 'bytes_value':
            return msg.bytes_value, sch.BYTE_ARR
        if name == 'char_arr_value':
            return msg.char_arr_value, sch.CHAR_ARR
        if name == 'short_arr_value':
            return list(msg.short_arr_value.arr), sch.SHORT_ARR
        if name == 'int_arr_value':
            return list(msg.int_arr_value.arr), sch.INT_ARR
        if name == 'long_arr_value':
            return list(msg.long_arr_value.arr), sch.LONG_ARR
        if name == 'string_arr_value':
            return list(msg.string_arr_value.arr), sch.STRING_ARR
        if name == 'address_value':
            return Client._read_address(msg.address_value), sch.ADDRESS
        if name == 'range_value':
            return Client._read_range(msg.range_value), sch.RANGE
        if name == 'child_desc':
            return Client._read_obj_desc(msg.child_desc), sch.OBJECT
        raise ValueError("Could not read value: {}".format(msg))

    def __init__(self, s, description: str, method_registry: MethodRegistry):
        self._traces: Dict[int, Trace] = {}
        self._next_trace_id: int = 1
        self.tlock: Lock = Lock()

        self.receiver: Receiver = Receiver(self)
        self.cur_batch: Optional[Batch] = None
        self._block: Lock = Lock()
        self.s: socket.socket = s
        self.slock: Lock = Lock()
        self.receiver.start()
        self._method_registry: MethodRegistry = method_registry
        self.description: str = self._negotiate(description)

    def __repr__(self) -> str:
        return f"<ghidratrace.Client {self.s}>"

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Upgrade the client and server to matching ghidratrace versions.
  2. Inspect the offending message (the exception prints msg) to identify the unexpected field name.
  3. If developing a new value kind, add a reader branch in _read_value before deploying.

Example fix

// not a code fix — version alignment
# before: client on old ghidratrace, server on new
# after: pin both ends to the same ghidratrace release
Defensive patterns

Strategy: try-catch

Try / catch

try:
    value = Client._read_value(msg)
except ValueError:
    log.error('Unsupported incoming Value field; likely version skew')
    raise

Prevention

When it happens

Trigger: A newer server sends a Value field type this older client cannot read; a corrupted or partially-constructed message; an unknown field that protobuf preserved as the which-oneof name.

Common situations: Client/server version skew where the server added a new value kind; truncated/garbled network data; testing with hand-built protobuf messages.

Related errors


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