NationalSecurityAgency/ghidra · error · IllegalArgumentException
{} is not a constant
Error message
{} is not a constant What it means
Thrown (unchecked IllegalArgumentException) by getIntConst(Varnode) when the passed varnode is not constant (vn.isConstant() is false). getIntConst reads a literal/immediate value directly from the varnode offset; a non-constant varnode (register/memory/unique) has no such immediate, so the precondition is violated.
Source
Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/eval/AbstractVarnodeEvaluator.java:364
* @param program the program defining the static context
* @param op the op whose output to evaluate
* @param already a cache of already-evaluated varnodes and their values
* @return the output value
*/
protected abstract T evaluatePtrSub(Program program, PcodeOp op, Map<Varnode, T> already);
/**
* Assert that a varnode is constant and get its value as an integer.
*
* <p>
* Here "constant" means a literal or immediate value. It does not read from the state.
*
* @param vn the varnode
* @return the value
*/
protected int getIntConst(Varnode vn) {
if (!vn.isConstant()) {
throw new IllegalArgumentException(vn + " is not a constant");
}
return (int) vn.getAddress().getOffset();
}
/**
* Evaluate a {@link PcodeOp#LOAD} op
*
* @param program the program defining the static context
* @param op the op whose output to evaluate
* @param already a cache of already-evaluated varnodes and their values
* @return the output value
*/
protected abstract T evaluateLoad(Program program, PcodeOp op, Map<Varnode, T> already);
@Override
public T evaluateOp(Program program, PcodeOp op) {
return evaluateOp(program, op, new HashMap<>());
}View on GitHub (pinned to d5f144c24d)
Solutions
- Guard with vn.isConstant() before calling getIntConst, and handle the non-constant case (e.g. evaluate it via evaluateVarnode).
- Double-check you are reading the correct operand index for the immediate.
- For ops with conditionally-constant operands, branch on isConstant rather than assuming it.
Example fix
// before int n = evaluator.getIntConst(op.getInput(1)); // throws if input is dynamic // after: check before reading Varnode in = op.getInput(1); int n = in.isConstant() ? evaluator.getIntConst(in) : (int) evaluator.evaluateVarnode(program, in, cache).getValue();
Defensive patterns
Strategy: validation
Validate before calling
// Check constancy before reading as int constant
if (!vn.isConstant()) {
// do not call getIntConst; evaluate the value instead
} Prevention
- Always guard getIntConst with vn.isConstant().
- Verify you read the correct (immediate) operand index for the op.
- Branch on isConstant for ops with conditionally-immediate operands.
When it happens
Trigger: Calling getIntConst on a varnode that is a register, memory reference, unique, or any computed value rather than an immediate operand. Typically inside an evaluateOp override that fetches an input operand expecting it to be immediate when it is not.
Common situations: Mis-assuming a p-code op's input is always immediate (e.g. for INT_ADD, CBUILD, STORE size input); evaluating p-code whose operands were constant-folded away or are dynamic; an op where the immediate is the second operand but code reads the first.
Related errors
- Unrecognized address space in {}
- No defining p-code op for {}
- Cannot evaluate unique $U%x:%d
- Encountered an unimplemented instruction at {}
- Unsupported p-code op at {}: {}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/385311f2946721ff.
Report an issue: GitHub.