{"record":{"id":"39d23dffb44273e6","repo":"mybatis/mybatis-3","slug":"too-many-default-otherwise-elements-in-choose-st","errorCode":null,"errorMessage":"Too many default (otherwise) elements in choose statement.","messagePattern":"Too many default \\(otherwise\\) elements in choose statement\\.","errorType":"exception","errorClass":"BuilderException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/scripting/xmltags/XMLScriptBuilder.java","lineNumber":261,"sourceCode":"      for (XNode child : children) {\n        String nodeName = child.getNode().getNodeName();\n        NodeHandler handler = nodeHandlerMap.get(nodeName);\n        if (handler instanceof IfHandler) {\n          handler.handleNode(child, ifSqlNodes);\n        } else if (handler instanceof OtherwiseHandler) {\n          handler.handleNode(child, defaultSqlNodes);\n        } else {\n          throw new BuilderException(\"Unknown element <\" + nodeName + \"> in SQL statement.\");\n        }\n      }\n    }\n\n    private SqlNode getDefaultSqlNode(List<SqlNode> defaultSqlNodes) {\n      SqlNode defaultSqlNode = null;\n      if (defaultSqlNodes.size() == 1) {\n        defaultSqlNode = defaultSqlNodes.get(0);\n      } else if (defaultSqlNodes.size() > 1) {\n        throw new BuilderException(\"Too many default (otherwise) elements in choose statement.\");\n      }\n      return defaultSqlNode;\n    }\n  }\n\n  private static class EmptySqlNode implements SqlNode {\n    private final String whitespaces;\n\n    public EmptySqlNode(String whitespaces) {\n      super();\n      this.whitespaces = whitespaces;\n    }\n\n    @Override\n    public boolean apply(DynamicContext context) {\n      context.appendSql(whitespaces);\n      return true;\n    }","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/scripting/xmltags/XMLScriptBuilder.java#L243-L279","documentation":"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.","triggerScenarios":"Two (or more) <otherwise> elements inside a single <choose> element in a mapper XML file.","commonSituations":"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.","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."],"exampleFix":"// before\n<choose>\n  <when test=\"a\">A</when>\n  <otherwise>B</otherwise>\n  <otherwise>C</otherwise>\n</choose>\n// after\n<choose>\n  <when test=\"a\">A</when>\n  <otherwise>B</otherwise>\n</choose>","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["mybatis","xml","choose","mapper-parsing","builder-exception"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}