JetBrains/intellij-community · error · EvaluateRuntimeException
Variable ''{0}'' is already declared
Error message
Variable ''{0}'' is already declared What it means
Thrown by CodeFragmentEvaluator.setInitialValue when code that builds an evaluation tries to register a synthetic local variable under a name that already exists in the current code fragment evaluator. It guards against silently shadowing an existing evaluation variable with a non-JDI seed value.
Source
Thrown at java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java:100
boolean hasValue(String localName) {
if (!mySyntheticLocals.containsKey(localName)) {
if (myParentFragmentEvaluator != null) {
return myParentFragmentEvaluator.hasValue(localName);
}
else {
return false;
}
}
else {
return true;
}
}
public void setInitialValue(String localName, Object value) {
LOG.assertTrue(!(value instanceof Value), "use setValue for jdi values");
if (hasValue(localName)) {
throw new EvaluateRuntimeException(
EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message("evaluation.error.variable.already.declared", localName)));
}
mySyntheticLocals.put(localName, value);
}
public void setValue(String localName, Value value) throws EvaluateException {
if (!mySyntheticLocals.containsKey(localName)) {
if (myParentFragmentEvaluator != null) {
myParentFragmentEvaluator.setValue(localName, value);
}
else {
throw EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message("evaluation.error.variable.not.declared", localName));
}
}
else {
mySyntheticLocals.put(localName, value);
}
}View on GitHub (pinned to be881553f2)
Solutions
- Use a unique variable name for each setInitialValue call
- Check hasValue(localName) before calling setInitialValue and use setValue for existing JDI values
- Create a fresh CodeFragmentEvaluator per evaluation instead of reusing one
Example fix
// before
fragment.setInitialValue("x", 1);
fragment.setInitialValue("x", 2); // throws
// after
if (fragment.hasValue("x")) {
fragment.setValue("x", debuggerValue);
} else {
fragment.setInitialValue("x", 1);
} Defensive patterns
Strategy: validation
Validate before calling
if (!fragment.hasValue(localName)) {
fragment.setInitialValue(localName, value);
} else {
fragment.setValue(localName, jdiValue); // or pick another name
} Try / catch
try {
evaluator.setInitialValue(name, value);
} catch (EvaluateRuntimeException e) {
if (e.getMessage().contains("already declared")) { /* rename variable */ }
} Prevention
- Always check hasValue(name) before setInitialValue
- Use a fresh CodeFragmentEvaluator per evaluation
- Never pass a JDI Value to setInitialValue — use setValue for mirrors
When it happens
Trigger: Calling setInitialValue(localName, value) twice with the same localName on the same CodeFragmentEvaluator, or registering a name already added by a previous statement; hasValue(localName) returns true and an EvaluateRuntimeException wrapping evaluation.error.variable.already.declared is thrown.
Common situations: Debugger internals or plugins (e.g. JVM debugger language injection, Groovy/Kotlin evaluators reusing fragments) that seed the same captured variable name twice; re-evaluating an expression against a reused evaluator instance without resetting synthetic locals.
Related errors
- Interface method invocation is not supported in JVM {}. Use
- Cannot construct wrapper object for value of type {}: Unable
- Local variable declarations are not supported here.
- Invalid declaration : {0} Only local variable declarations a
- inconvertible.type.cast
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/1ce77a2e223c99fa.
Report an issue: GitHub.