NationalSecurityAgency/ghidra · error · IllegalArgumentException
Length must match the register
Error message
Length must match the register
What it means
Thrown by DBTraceObjectRegister.setValue() when the byte array value's length does not match the register's expected byte length. The method computes length = getByteLength(lifespan.lmin()) and checks length != 0 (meaning the register size is known) and value.length != length. An IllegalArgumentException (unchecked) enforces that register writes must use exactly the register's native width.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceObjectRegister.java:68
}
@Override
public String getName() {
KeyPath path = object.getCanonicalPath();
return KeyPath.parseIfIndex(path.key());
}
@Override
public int getBitLength(long snap) {
return TraceObjectInterfaceUtils.getValue(object, snap, TraceRegister.KEY_BITLENGTH,
Integer.class, 0);
}
@Override
public void setValue(Lifespan lifespan, byte[] value) {
int length = getByteLength(lifespan.lmin());
if (length != 0 && value.length != length) {
throw new IllegalArgumentException("Length must match the register");
}
object.setValue(lifespan, TraceRegister.KEY_VALUE, value);
}
@Override
public byte[] getValue(long snap) {
TraceObjectValue ov = object.getValue(snap, TraceRegister.KEY_VALUE);
if (ov == null) {
return null;
}
Object val = ov.getValue();
if (val instanceof byte[] arr) {
// TODO: Should I correct mismatched size?
return arr;
}
if (val instanceof String str) {
// Always base 16. Model API says byte array for register value is big endian.
BigInteger bigVal = new BigInteger(str, 16);View on GitHub (pinned to d5f144c24d)
Solutions
- Pad or truncate the byte array to match getByteLength(snap) before calling setValue().
- Use Utils.bigIntegerToBytes(BigInteger.valueOf(val), reg.getByteLength(snap), true) to generate a correctly-sized byte array.
- Verify the register's bit length via getBitLength(snap) and compute expected byte length before writing.
Example fix
// before reg.setValue(lifespan, rawBytes); // rawBytes.length != expected // after int expectedLen = reg.getByteLength(lifespan.lmin()); byte[] fixed = Arrays.copyOf(rawBytes, expectedLen); reg.setValue(lifespan, fixed);
Defensive patterns
Strategy: validation
Validate before calling
// Verify byte length matches before setting register value
int expectedLen = reg.getByteLength(lifespan.lmin());
if (expectedLen != 0 && value.length != expectedLen) {
value = Arrays.copyOf(value, expectedLen); // pad or truncate
}
reg.setValue(lifespan, value); Prevention
- Always size byte arrays to match getByteLength(snap) before calling setValue().
- Use Utils.bigIntegerToBytes() to generate correctly-sized arrays.
- Check getBitLength(snap) to compute expected byte length.
When it happens
Trigger: Calling setValue(lifespan, value) on a DBTraceObjectRegister where value.length differs from the register's byte length at the given snap. For example, writing a 4-byte array to an 8-byte register, or a 2-byte array to a 1-byte register. The check is skipped only when getByteLength returns 0 (register size unknown at that snap).
Common situations: Recording register values from a target whose register width differs from the trace's language definition. Endianness or width conversion errors when preparing register values. Using a register value from one architecture in a trace configured for another.
Related errors
- data and mask must have same capacity
- Cannot convert
- Space must be a memory, register, or NO_ADDRESS space
- Byte arrays cannot exceed length of variable
- Must have id or path
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/c5f0898859ddb5c6.
Report an issue: GitHub.