NationalSecurityAgency/ghidra · error · IllegalStateException
Cannot write to watch variable without an address
Error message
Cannot write to watch variable without an address
What it means
Thrown by DefaultWatchRow.setRawValueBytes when the watch row's address is null. A watch cannot be written until it has been resolved to a concrete address in the current trace/coordinates.
Source
Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DefaultWatchRow.java:463
}
public void setRawValueIntString(String intString) {
intString = intString.trim();
final BigInteger val;
if (intString.startsWith("0x")) {
val = new BigInteger(intString.substring(2), 16);
}
else {
val = new BigInteger(intString, 10);
}
setRawValueBytes(
Utils.bigIntegerToBytes(val, value.length, provider.language.isBigEndian()));
}
public void setRawValueBytes(byte[] bytes) {
synchronized (lock) {
if (address == null) {
throw new IllegalStateException(
"Cannot write to watch variable without an address");
}
if (bytes.length > value.length) {
throw new IllegalArgumentException("Byte arrays cannot exceed length of variable");
}
if (bytes.length < value.length) {
byte[] fillOld = Arrays.copyOf(value, value.length);
System.arraycopy(bytes, 0, fillOld, 0, bytes.length);
bytes = fillOld;
}
DebuggerControlService controlService = provider.controlService;
if (controlService == null) {
throw new AssertionError("No control service");
}
StateEditor editor = controlService.createStateEditor(provider.current);
editor.setVariable(address, bytes).exceptionally(ex -> {
Msg.showError(this, null, "Write Failed",
"Could not modify watch value (on target)", ex);View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure the debug target/emulator is live and the watch's address is resolved (non-null) before editing.
- Call isRawValueEditable() / check address != null before attempting a write.
- Re-resolve the watch by switching to valid coordinates or refreshing the target.
- Remove and re-add the watch so its address rebinds.
Example fix
// before
row.setRawValueBytes(bytes); // throws if address == null
// after
if (row.getAddress() == null) {
Msg.warn(this, "Watch has no address; cannot write");
return;
}
row.setRawValueBytes(bytes); Defensive patterns
Strategy: validation
Validate before calling
boolean writable = row.isRawValueEditable() && row.getAddress() != null;
Type guard
static boolean watchHasAddress(DefaultWatchRow r) {
return r.getAddress() != null;
} Try / catch
try {
row.setRawValueBytes(bytes);
} catch (IllegalStateException e) {
Msg.showWarn(this, null, "Watch unresolved", e.getMessage());
} Prevention
- Wait for target live + symbol resolution before editing watches.
- Rebind stale watches to valid coordinates.
When it happens
Trigger: Calling setRawValueBytes while the row's address field is null (the watch expression has not been resolved to a location, or the current coordinates do not map it).
Common situations: Editing a watch before the target is running and symbols resolved; watch on a symbol/register not present in the current platform; stale watch row left from a disconnected session.
Related errors
- Could not set target memory
- Byte array values must be hex enclosed in {}
- Byte arrays cannot exceed length of variable
- Address does not belong to a memory in the trace
- Bad address format: {}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/3a3426a8d68eeb5e.
Report an issue: GitHub.