baomidou/mybatis-plus · error · BuilderException

Too many default (otherwise) elements in choose statement.

Error message

Too many default (otherwise) elements in choose statement.

What it means

Within a single <choose> element, more than one <otherwise> branch was found. The choose/when/otherwise construct models if/else-if/else, so at most one default (otherwise) branch is allowed; the builder enforces this while assembling the default SqlNode.

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisXMLScriptBuilder.java:320

        private void handleWhenOtherwiseNodes(XNode chooseSqlNode, List<SqlNode> ifSqlNodes, List<SqlNode> defaultSqlNodes) {
            List<XNode> children = chooseSqlNode.getChildren();
            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);
                }
            }
        }

        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;
        }
    }

}

View on GitHub (pinned to bf67d90747)

Solutions

  1. Locate the choose block in the mapper named by the parse error and delete all but one <otherwise>
  2. If multiple fallback conditions are truly needed, convert the extra <otherwise> blocks into <when test="..."> branches with explicit conditions
  3. Refactor long choose blocks into <sql>/<include> fragments to reduce merge-conflict risk

Example fix

<!-- before -->
<choose>
  <when test="a">A</when>
  <otherwise>B</otherwise>
  <otherwise>C</otherwise>
</choose>
<!-- after -->
<choose>
  <when test="a">A</when>
  <when test="b">B</when>
  <otherwise>C</otherwise>
</choose>
Defensive patterns

Strategy: validation

Validate before calling

// Check choose blocks during build: at most one otherwise
Element choose = (Element) node;
int otherwiseCount = choose.getElementsByTagName("otherwise").getLength();
if (otherwiseCount > 1) throw new IllegalStateException("choose has " + otherwiseCount + " otherwise blocks");

Prevention

When it happens

Trigger: A <choose> block containing two or more <otherwise> elements, usually from copy-pasting a <when> block and forgetting to change the tag, or merged XML from a bad conflict resolution.

Common situations: Git merge conflicts resolved by keeping both branches; copy-paste of conditional blocks; hand-editing long dynamic SQL.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/f896e8786a95fdbf. Report an issue: GitHub.