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

  1. Ensure the debug target/emulator is live and the watch's address is resolved (non-null) before editing.
  2. Call isRawValueEditable() / check address != null before attempting a write.
  3. Re-resolve the watch by switching to valid coordinates or refreshing the target.
  4. 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

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


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