mybatis/mybatis-3 · error · BuilderException
Error evaluating expression '" + expression + "'. Return va
Error message
Error evaluating expression '" + expression + "'. Return value (" + value + ") was not iterable. What it means
MyBatis throws this BuilderException when ExpressionEvaluator.evaluateIterable() is asked to iterate a value whose runtime type is neither an array, a java.lang.Iterable, nor a java.util.Map. It is raised from the <foreach> dynamic SQL construct: the expression given in the 'collection' (or 'item' list source) attribute must resolve to something walkable. Any scalar (Integer, String, single POJO) result makes the SQL node unbuildable at execution time.
Source
Thrown at src/main/java/org/apache/ibatis/scripting/xmltags/ExpressionEvaluator.java:81
if (value instanceof Iterable) {
return (Iterable<?>) value;
}
if (value.getClass().isArray()) {
// the array may be primitive, so Arrays.asList() may throw
// a ClassCastException (issue 209). Do the work manually
// Curse primitives! :) (JGB)
int size = Array.getLength(value);
List<Object> answer = new ArrayList<>();
for (int i = 0; i < size; i++) {
Object o = Array.get(value, i);
answer.add(o);
}
return answer;
}
if (value instanceof Map) {
return ((Map) value).entrySet();
}
throw new BuilderException(
"Error evaluating expression '" + expression + "'. Return value (" + value + ") was not iterable.");
}
}
View on GitHub (pinned to 008069adb1)
Solutions
- Make the collection attribute point at an actual List/Set/array/Map property (e.g. collection="ids" where ids is List<Long>).
- If the input is naturally scalar or null, wrap it before the call: Collections.singletonList(value).
- Check the OGNL path spelling against the parameter object's getters; a wrong path can resolve to an unrelated scalar property.
- For comma-separated input, split it in the mapper/service layer into a List before passing to MyBatis.
Example fix
// before
<select id="findByIds" parameterType="map">
SELECT * FROM t WHERE id IN
<foreach item="id" collection="id">#{id}</foreach>
</select>
// after
<select id="findByIds" parameterType="map">
SELECT * FROM t WHERE id IN
<foreach item="id" collection="ids">#{id}</foreach>
</select>
// with map.put("ids", Arrays.asList(1,2,3)) Defensive patterns
Strategy: validation
Validate before calling
Object v = ((Map<String, Object>) paramMap).get("ids");
boolean ok = v == null || v instanceof Iterable || v.getClass().isArray() || v instanceof Map;
if (!ok) throw new IllegalArgumentException("ids must be List/Set/array/Map, was " + (v == null ? "null" : v.getClass())); Try / catch
try { sqlSession.selectList("findByIds", paramMap); }
catch (BuilderException e) { /* check 'was not iterable' in message; fix collection attribute */ throw e; } Prevention
- Type mapper parameters as List<T>/Set<T>/T[] explicitly instead of Object.
- Prefer @Param names that mirror the collection attribute string in XML.
- Wrap scalar or null inputs with Collections.singletonList()/emptyList before the call.
When it happens
Trigger: A <foreach item="x" collection="ids" ...> where the parameter object's 'ids' property is a single Integer/String/POJO instead of a List/Set/array/Map; an OGNL expression in collection="..." that evaluates to a scalar (e.g. collection="user.id" instead of "user.ids"); passing a single object where the mapper method signature declares a collection.
Common situations: Mapper method takes Object/POJO but XML assumes a list; property name typo so OGNL falls back to a scalar getter; refactoring a List parameter to a single item without updating the XML; passing a String of comma-separated ids instead of a List.
Related errors
- The expression '" + expression + "' evaluated to a null valu
- Error evaluating expression '" + expression + "'. Cause: " +
- Parsing error was found in mapping #{{content}}. Check synt
- There is no getter for property named '{}' in '{}'
- Invalid index syntax in property: '{}'. Missing closing brac
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/27f24063e3ad7d1d.
Report an issue: GitHub.