{"record":{"id":"6f45dfe70ba89208","repo":"mybatis/mybatis-3","slug":"unknown-element-nodename-in-sql-statemen","errorCode":null,"errorMessage":"Unknown element <\" + nodeName + \"> in SQL statement.","messagePattern":"Unknown element <\" \\+ nodeName \\+ \"> in SQL statement\\.","errorType":"exception","errorClass":"BuilderException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/scripting/xmltags/XMLScriptBuilder.java","lineNumber":108,"sourceCode":"      XNode child = node.newXNode(children.item(i));\n      if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE || child.getNode().getNodeType() == Node.TEXT_NODE) {\n        String data = child.getStringBody(\"\");\n        if (data.trim().isEmpty()) {\n          contents.add(emptyNodeCache.computeIfAbsent(data, EmptySqlNode::new));\n          continue;\n        }\n        TextSqlNode textSqlNode = new TextSqlNode(data);\n        if (textSqlNode.isDynamic()) {\n          contents.add(textSqlNode);\n          isDynamic = true;\n        } else {\n          contents.add(new StaticTextSqlNode(data));\n        }\n      } else if (child.getNode().getNodeType() == Node.ELEMENT_NODE) { // issue #628\n        String nodeName = child.getNode().getNodeName();\n        NodeHandler handler = nodeHandlerMap.get(nodeName);\n        if (handler == null) {\n          throw new BuilderException(\"Unknown element <\" + nodeName + \"> in SQL statement.\");\n        }\n        handler.handleNode(child, contents);\n        isDynamic = true;\n      }\n    }\n    return new MixedSqlNode(contents);\n  }\n\n  private interface NodeHandler {\n    void handleNode(XNode nodeToHandle, List<SqlNode> targetContents);\n  }\n\n  private static class BindHandler implements NodeHandler {\n    public BindHandler() {\n      // Prevent Synthetic Access\n    }\n\n    @Override","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/scripting/xmltags/XMLScriptBuilder.java#L90-L126","documentation":"XMLScriptBuilder parses the body of a statement mapped to XMLLanguageDriver and only recognizes MyBatis' own dynamic SQL tags (if, choose, when, otherwise, trim, where, set, foreach, bind) plus text. When a child element's node name has no registered NodeHandler, this BuilderException is thrown at configuration/mapper-parsing time. It almost always means a misspelled or non-MyBatis XML element inside a SELECT/INSERT/UPDATE/DELETE (or sql fragment) block.","triggerScenarios":"A typo such as <wher>, <ifo>, <foreache> inside a statement body; using JSTL or custom tags like <c:if> inside MyBatis XML; a stray namespace prefix element; nesting a <select> or other top-level mapper element inside a statement body by mistake.","commonSituations":"Hand-editing mapper XML and misspelling a dynamic tag; copy-pasting from a JSP/JSTL template; XML IDE auto-completing the wrong tag; editing an included <sql> fragment with an element type not valid there.","solutions":["Open the mapper XML named in the stack trace and fix the element shown in <...> to one of: if, choose, when, otherwise, trim, where, set, foreach, bind.","Remove non-MyBatis/JSTL tags from statement bodies; move that logic into OGNL test expressions or provider-based SQL.","Re-run and let the parser confirm the next error until the file is clean (it fails fast on the first bad element)."],"exampleFix":"// before\n<select id=\"find\" resultMap=\"r\">\n  SELECT * FROM t\n  <wher><if test=\"id != null\">id = #{id}</if></wher>\n</select>\n// after\n<select id=\"find\" resultMap=\"r\">\n  SELECT * FROM t\n  <where><if test=\"id != null\">id = #{id}</if></where>\n</select>","handlingStrategy":"validation","validationCode":"// Fast-fail at startup: parse all mappers eagerly\nSqlSessionFactory f = new SqlSessionFactoryBuilder().build(cfgXml);\n// parsing happens at build(); any unknown element throws here, before serving traffic","typeGuard":null,"tryCatchPattern":"try { factory = builder.build(in); }\ncatch (BuilderException e) { /* fail startup with mapper file + element name */ throw e; }","preventionTips":["Build the SqlSessionFactory once at application startup so XML errors fail fast.","Enable XML schema/DTD validation in the IDE for mapper files.","Restrict dynamic tags to the known set: if, choose/when/otherwise, trim, where, set, foreach, bind."],"tags":["mybatis","xml","mapper-parsing","builder-exception"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}