JetBrains/intellij-community · error · EvaluateException
Unable to set value
Error message
Unable to set value
What it means
Thrown by LocalVariablesUtil when setting a value of a decompiled local variable fails. This path uses reflection to drive the JDI SlotInfo/set protocol for variables with no local-variable table (classes compiled without debug info); any reflective or invocation failure is wrapped in EvaluateException('Unable to set value').
Source
Thrown at java/debugger/impl/src/com/intellij/debugger/jdi/LocalVariablesUtil.java:273
else {
final Long frameId = ReflectionUtil.getField(frame.getClass(), frame, long.class, "id");
final VirtualMachine vm = frame.virtualMachine();
final Method stateMethod = vm.getClass().getDeclaredMethod("state");
stateMethod.setAccessible(true);
Object slotInfoArray = createSlotInfoArraySet(variable.slot(), value);
Object ps;
final Object vmState = stateMethod.invoke(vm);
synchronized (vmState) {
ps = ourEnqueueMethodSet.invoke(null, vm, frame.thread(), frameId, slotInfoArray);
}
ourWaitForReplyMethodSet.invoke(null, vm, ps);
}
}
catch (Exception e) {
throw new EvaluateException("Unable to set value", e);
}
}
private static Object createSlotInfoArraySet(int slot, Value value)
throws IllegalAccessException, InvocationTargetException, InstantiationException {
Object arrayInstance = Array.newInstance(ourSlotInfoClassSet, 1);
Array.set(arrayInstance, 0, slotInfoConstructorSet.newInstance(slot, value));
return arrayInstance;
}
private static Object createSlotInfoArray(Collection<? extends DecompiledLocalVariable> vars) throws Exception {
final Object arrayInstance = Array.newInstance(ourSlotInfoClass, vars.size());
int idx = 0;
for (DecompiledLocalVariable var : vars) {
final Object info = slotInfoConstructor.newInstance(var.slot(), (byte)var.signature().charAt(0));
Array.set(arrayInstance, idx++, info);
}View on GitHub (pinned to be881553f2)
Solutions
- Recompile the debuggee with debug info (-g or gradle/maven debug flag) so real LocalVariables exist instead of decompiled slots
- Ensure the assigned value's type exactly matches the variable's expected type (no implicit conversions in slot assignment)
- Update the IDE — reflective JDI internals change between JDK versions and are patched per-JDK
Example fix
# before javac Main.java # no -g, decompiled slots # after javac -g Main.java
Defensive patterns
Strategy: try-catch
Validate before calling
// before assigning to a decompiled variable
if (!(variable instanceof DecompiledLocalVariable)) {
frame.setValue(variable, value);
} else {
// ensure value type matches slot type exactly; otherwise wrap/cast first
} Type guard
boolean isSafeSlotAssignment(DecompiledLocalVariable v, Value value) {
return value == null || v.typeName().equals(value.type().name());
} Try / catch
try {
LocalVariablesUtil.setValue(frame, variable, value);
} catch (EvaluateException e) {
// 'Unable to set value': report slot/type mismatch, suggest recompiling with -g
} Prevention
- Compile debuggee classes with -g to produce real local variable tables
- Match assigned value types exactly for slot-based variables
- Keep the IDE updated for JDI-internal compatibility fixes
When it happens
Trigger: Calling the setValue path for a DecompiledLocalVariable: it reflects into the VM state object, builds a SlotInfo array via createSlotInfoArraySet(variable.slot(), value), invokes the enqueue/WaitForReply JDI internals; ClassNotFoundException/IllegalAccessException/InvocationTargetException from the reflection setup or the reflective call itself is caught by 'catch (Exception e)' and rethrown as EvaluateException.
Common situations: Debugging classes compiled without -g (no local variable table) so the debugger decompiles variables; assigning to such a variable in the Variables view or evaluator while the JDI internals reject the value type for the slot; JDI implementation differences across JDK versions breaking the reflective protocol.
Related errors
- Interface method invocation is not supported in JVM {}. Use
- Cannot construct wrapper object for value of type {}: Unable
- Cannot convert to primitive value of type
- Thread has been collected
- There is no executable code at {0}:{1}
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/cdbf616a4b36cda2.
Report an issue: GitHub.