JetBrains/intellij-community · error · EvaluateException

Unable to do foreach for

Error message

Unable to do foreach for

What it means

Thrown by ForeachStatementEvaluator.evaluate when the iterable expression of an enhanced-for loop in the evaluated fragment evaluates to something that is not an ObjectReference in the debuggee VM (null, a raw primitive, a void result). Without an ObjectReference (ArrayReference or Iterable object) the foreach machinery cannot iterate, so it aborts. Note the missing space in the original message concatenation.

Source

Thrown at java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java:32

  private final Evaluator myIterableEvaluator;
  private final Evaluator myBodyEvaluator;
  private final String myLabelName;

  public ForeachStatementEvaluator(Evaluator iterationParameterEvaluator,
                                   Evaluator iterableEvaluator,
                                   Evaluator bodyEvaluator,
                                   String labelName) {
    myIterationParameterEvaluator = iterationParameterEvaluator;
    myIterableEvaluator = DisableGC.create(iterableEvaluator);
    myBodyEvaluator = bodyEvaluator;
    myLabelName = labelName;
  }

  @Override
  public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
    final Object iterable = myIterableEvaluator.evaluate(context);
    if (!(iterable instanceof ObjectReference)) {
      throw new EvaluateException("Unable to do foreach for" + iterable);
    }

    if (iterable instanceof ArrayReference) {
      return new ForStatementEvaluatorBase(myLabelName, myBodyEvaluator) {
        private int myCurrentIndex = 0;
        private int myArrayLength = -1;
        private Evaluator myNextEvaluator;

        @Override
        protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException {
          myArrayLength = ((ArrayReference)iterable).length();
          myNextEvaluator = new AssignmentEvaluator(myIterationParameterEvaluator,
                                                    new Evaluator() {
                                                      @Override
                                                      public Object evaluate(EvaluationContextImpl context) {
                                                        return ((ArrayReference)iterable).getValue(myCurrentIndex++);
                                                      }
                                                    });

View on GitHub (pinned to be881553f2)

Solutions

  1. Check the iterable is non-null and is an array or Iterable before the loop: for (x : Objects.requireNonNull(list))
  2. For maps, iterate map.entrySet() or map.keySet() instead of the map itself
  3. Step the debugger to a point where the collection is initialized, then evaluate

Example fix

// before: for (String s : names) { ... }  // names is null

// after: for (String s : java.util.List.of("a")) { ... }
// or evaluate later, after names is assigned
Defensive patterns

Strategy: validation

Validate before calling

Object iterable = iterableEvaluator.evaluate(context);
if (!(iterable instanceof ObjectReference)) {
  throw new EvaluateException("Unable to do foreach for " + iterable);
}
// guard before: check the collection variable is non-null at this breakpoint

Type guard

static boolean isForeachable(Object evaluated) {
  return evaluated instanceof ObjectReference; // ArrayReference or Iterable mirror
}

Try / catch

try {
  foreachEvaluator.evaluate(context);
} catch (EvaluateException e) {
  // inspect the iterable expression alone; if null, skip the loop
}

Prevention

When it happens

Trigger: Evaluating 'for (x : expr) {...}' where myIterableEvaluator.evaluate(context) returns null (NPE in the evaluated provider, method returned void) or a PrimitiveValue; instanceof ObjectReference fails and EvaluateException('Unable to do foreach for' + iterable) is thrown.

Common situations: Evaluating a foreach over a variable that is null at the breakpoint; iterating over a primitive-typed expression; the iterable's getter threw inside the debuggee and the evaluator propagated null; evaluating a foreach over a Map instead of map.entrySet().

Related errors


AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14). Data as JSON: /api/errors/5f98838e61e74f1d. Report an issue: GitHub.