NationalSecurityAgency/ghidra · error · RegisterValueException

Cannot convert register value: ({class}) '{val}'

Error message

Cannot convert register value: ({class}) '{val}'

What it means

Thrown by RegisterValueConverter.convertValueToBigInteger for a value whose Java type is none of the supported cases (String, byte[], Byte, Short, Integer, Long, Address). The converter cannot turn an arbitrary object into a BigInteger register value, so it reports the unexpected class and value.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/memory/RegisterValueConverter.java:64

			// NOTE: Reg object values are always big endian
			return new BigInteger(1, arr);
		}
		else if (val instanceof Byte b) {
			return BigInteger.valueOf(b);
		}
		else if (val instanceof Short s) {
			return BigInteger.valueOf(s);
		}
		else if (val instanceof Integer i) {
			return BigInteger.valueOf(i);
		}
		else if (val instanceof Long l) {
			return BigInteger.valueOf(l);
		}
		else if (val instanceof Address a) {
			return a.getOffsetAsBigInteger();
		}
		throw new RegisterValueException(
			"Cannot convert register value: (" + val.getClass() + ") '" + val + "'");
	}

	BigInteger convertRegisterValueToBigInteger() throws RegisterValueException {
		return convertValueToBigInteger(registerValue.getValue());
	}

	int getRegisterValueBitLength() throws RegisterValueException {
		Object objBitLength = registerValue.getParent()
				.getValue(registerValue.getMinSnap(), TraceRegister.KEY_BITLENGTH)
				.getValue();
		if (!(objBitLength instanceof Number numBitLength)) {
			throw new RegisterValueException(
				"Register length is not numeric: (" + objBitLength.getClass() + ") '" +
					objBitLength + "'");
		}
		return numBitLength.intValue();
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Store the register value as one of the supported types (prefer byte[] or a hex String).
  2. Convert the value to a supported type before attaching it to the register object.
  3. Catch RegisterValueException and log the class/value to locate the mis-typed source.

Example fix

// before
obj.setAttribute(span, regKey, bigIntValue /* BigInteger - unsupported */);

// after
obj.setAttribute(span, regKey, bigIntValue.toByteArray()); // byte[] supported
Defensive patterns

Strategy: try-catch

Validate before calling

if (!(val instanceof String || val instanceof byte[]
        || val instanceof Number || val instanceof Address)) {
    val = toSupported(val); // e.g. BigInteger -> byte[], or Long[] -> byte[]
}

Type guard

static boolean supportedValueType(Object val) {
    return val instanceof String || val instanceof byte[]
        || val instanceof Byte || val instanceof Short
        || val instanceof Integer || val instanceof Long
        || val instanceof Address;
}

Try / catch

try {
    BigInteger v = new RegisterValueConverter(regVal).getValue();
} catch (RegisterValueException e) {
    // log val.getClass() from e.getMessage(); coerce source type and retry
}

Prevention

When it happens

Trigger: A TraceObjectValue's register value is of an unsupported type such as Long[], BigInteger, Boolean, a composite object, or a list/map, and getValue() is called on its converter.

Common situations: A target connector serializes registers into an array or BigInteger instead of a primitive/byte[]; schema changes that store values differently; prototype/test data with wrong types.

Related errors


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