NationalSecurityAgency/ghidra · error · ValueError
Invalid memory state: {}
Error message
Invalid memory state: {} What it means
Raised by Trace.validate_state() when the supplied memory-state string is not one of 'unknown', 'known', or 'error'. These three states classify a memory range's validity in a Ghidra trace. set_memory_state() calls validate_state() to guard the value before sending it over RMI, so any unrecognized string is rejected before serialization.
Source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py:363
def create_overlay_space(self, base: str, name: str) -> Union[
None, RemoteResult[Any, None]]:
if name in self.overlays:
return None
result = self.client._create_overlay_space(self.id, base, name)
self.overlays.add(name)
return result
def put_bytes(self, address: Address, data: bytes,
snap: Optional[int] = None) -> Union[
int, RemoteResult[Any, int]]:
if snap is None:
snap = self.snap()
return self.client._put_bytes(self.id, snap, address, data)
@staticmethod
def validate_state(state) -> None:
if not state in ('unknown', 'known', 'error'):
raise ValueError("Invalid memory state: {}".format(state))
def set_memory_state(self, range: AddressRange, state: str,
snap: Optional[int] = None) -> Union[
None, RemoteResult[Any, None]]:
if snap is None:
snap = self.snap()
return self.client._set_memory_state(self.id, snap, range, state)
def delete_bytes(self, range: AddressRange, snap:
Optional[int] = None) -> Union[
None, RemoteResult[Any, None]]:
if snap is None:
snap = self.snap()
return self.client._delete_bytes(self.id, snap, range)
def put_registers(self, space: str, values: Iterable[RegVal],
snap: Optional[int] = None) -> Union[
List[str], RemoteResult[Any, List[str]]]:View on GitHub (pinned to d5f144c24d)
Solutions
- Use the exact literals: 'unknown', 'known', or 'error' (lowercase).
- Define a module-level constant or Enum and source every call from it so typos are compile-time caught.
- Add an allowlist check: if state not in ('unknown','known','error'): before calling set_memory_state.
Example fix
# before
trace.set_memory_state(rng, 'valid')
# after
VALID_STATES = ('unknown', 'known', 'error')
assert state in VALID_STATES, f'bad state {state!r}'
trace.set_memory_state(rng, state) Defensive patterns
Strategy: validation
Validate before calling
MEM_STATES = ('unknown', 'known', 'error')
if state not in MEM_STATES:
raise ValueError(f'Invalid memory state {state!r}; use one of {MEM_STATES}') Type guard
def is_valid_mem_state(s) -> bool:
return s in ('unknown', 'known', 'error') Prevention
- Centralize the three valid states in one constant.
- Never accept arbitrary strings from backends without mapping to the known vocabulary.
When it happens
Trigger: Calling trace.set_memory_state(range, 'cached'), passing 'True'/'TRUE', typos like 'know', or forwarding a state pulled from another tool's vocabulary (e.g. 'dirty', 'valid', 'invalid').
Common situations: Mapping between a debugger backend's memory-state enum and Ghidra's three-state vocabulary; user-typed config; code that assumed boolean or extra states exist.
Related errors
- No saved offers to launch {}
- Range [%s:%x+%x] entirely exceeds space min
- Trace is not from this connection
- CreateTrace: path (name) cannot be empty
- snap or time required
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/e64d381493a61014.
Report an issue: GitHub.