mybatis/mybatis-3 · error · BuilderException
Too many default (otherwise) elements in choose statement.
Error message
Too many default (otherwise) elements in choose statement.
What it means
When XMLScriptBuilder builds a <choose> node it collects all <otherwise> children into defaultSqlNodes; getDefaultSqlNode() allows at most one and throws this BuilderException when more than one is present. A <choose> models a switch: N <when> branches plus at most one <otherwise> default. The error surfaces during mapper parsing, before any SQL runs.
Source
Thrown at src/main/java/org/apache/ibatis/scripting/xmltags/XMLScriptBuilder.java:261
for (XNode child : children) {
String nodeName = child.getNode().getNodeName();
NodeHandler handler = nodeHandlerMap.get(nodeName);
if (handler instanceof IfHandler) {
handler.handleNode(child, ifSqlNodes);
} else if (handler instanceof OtherwiseHandler) {
handler.handleNode(child, defaultSqlNodes);
} else {
throw new BuilderException("Unknown element <" + nodeName + "> in SQL statement.");
}
}
}
private SqlNode getDefaultSqlNode(List<SqlNode> defaultSqlNodes) {
SqlNode defaultSqlNode = null;
if (defaultSqlNodes.size() == 1) {
defaultSqlNode = defaultSqlNodes.get(0);
} else if (defaultSqlNodes.size() > 1) {
throw new BuilderException("Too many default (otherwise) elements in choose statement.");
}
return defaultSqlNode;
}
}
private static class EmptySqlNode implements SqlNode {
private final String whitespaces;
public EmptySqlNode(String whitespaces) {
super();
this.whitespaces = whitespaces;
}
@Override
public boolean apply(DynamicContext context) {
context.appendSql(whitespaces);
return true;
}View on GitHub (pinned to 008069adb1)
Solutions
- Delete all but one <otherwise> in the offending <choose>.
- If two different defaults are genuinely needed, restructure into nested <choose> or additional <when test=...> branches with explicit conditions.
Example fix
// before <choose> <when test="a">A</when> <otherwise>B</otherwise> <otherwise>C</otherwise> </choose> // after <choose> <when test="a">A</when> <otherwise>B</otherwise> </choose>
Defensive patterns
Strategy: validation
Prevention
- Treat <choose> as switch: many <when>, at most one <otherwise>.
- After merging branches in a choose, count the otherwise tags (grep '>otherwise<' in the block).
- Parse all mappers at factory build time so this fails in CI.
When it happens
Trigger: Two (or more) <otherwise> elements inside a single <choose> element in a mapper XML file.
Common situations: Copy-pasting a <when> branch and renaming it to <otherwise> while an existing <otherwise> remains; merging branches during refactoring and forgetting to delete the old default; large hand-maintained choose blocks.
Related errors
- Unknown element <" + nodeName + "> in SQL statement.
- Error evaluating XPath. Cause: {}
- Error creating document instance. Cause: {}
- Error evaluating expression '" + expression + "'. Return va
- Error evaluating expression '" + expression + "'. Cause: " +
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/39d23dffb44273e6.
Report an issue: GitHub.