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

  1. Delete all but one <otherwise> in the offending <choose>.
  2. 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

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


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/39d23dffb44273e6. Report an issue: GitHub.