{"record":{"id":"1c2d9ef386969f9a","repo":"mybatis/mybatis-3","slug":"mapper-s-namespace-cannot-be-empty","errorCode":null,"errorMessage":"Mapper's namespace cannot be empty","messagePattern":"Mapper's namespace cannot be empty","errorType":"validation","errorClass":"BuilderException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java","lineNumber":122,"sourceCode":"    if (!configuration.isResourceLoaded(resource)) {\n      configurationElement(parser.evalNode(\"/mapper\"));\n      configuration.addLoadedResource(resource);\n      bindMapperForNamespace();\n    }\n    configuration.parsePendingResultMaps(false);\n    configuration.parsePendingCacheRefs(false);\n    configuration.parsePendingStatements(false);\n  }\n\n  public XNode getSqlFragment(String refid) {\n    return sqlFragments.get(refid);\n  }\n\n  private void configurationElement(XNode context) {\n    try {\n      String namespace = context.getStringAttribute(\"namespace\");\n      if (namespace == null || namespace.isEmpty()) {\n        throw new BuilderException(\"Mapper's namespace cannot be empty\");\n      }\n      builderAssistant.setCurrentNamespace(namespace);\n      cacheRefElement(context.evalNode(\"cache-ref\"));\n      cacheElement(context.evalNode(\"cache\"));\n      parameterMapElement(context.evalNodes(\"/mapper/parameterMap\"));\n      resultMapElements(context.evalNodes(\"/mapper/resultMap\"));\n      sqlElement(context.evalNodes(\"/mapper/sql\"));\n      buildStatementFromContext(context.evalNodes(\"select|insert|update|delete\"));\n    } catch (Exception e) {\n      throw new BuilderException(\"Error parsing Mapper XML. The XML location is '\" + resource + \"'. Cause: \" + e, e);\n    }\n  }\n\n  private void buildStatementFromContext(List<XNode> list) {\n    if (configuration.getDatabaseId() != null) {\n      buildStatementFromContext(list, configuration.getDatabaseId());\n    }\n    buildStatementFromContext(list, null);","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java#L104-L140","documentation":"Thrown by XMLMapperBuilder.configurationElement() when the <mapper> root element of a mapper XML file has no namespace attribute or an empty one. The namespace is the mapper's identity: it binds the XML to a Java interface and prefixes every statement id, fragment id and cache-ref, so an empty namespace is fatal. Note this is usually re-wrapped as 'Error parsing Mapper XML' (error 67) with this as the cause.","triggerScenarios":"<mapper> without a namespace attribute: <mapper>...</mapper>; or namespace=\"\" (empty string). Raised when the mapper XML is parsed, whether loaded via <mapper resource=...>, url, or automatically alongside an interface.","commonSituations":"New hand-written mapper XML from a blank template; trimming the file and deleting the root element's attributes; namespace typed as a path (slashes) or with leading/trailing whitespace-only content; mapper XML placed in the same package as the interface but with missing namespace during annotation+XML mixed setups.","solutions":["Set namespace to the fully-qualified name of the corresponding mapper interface, e.g. <mapper namespace=\"com.acme.UserMapper\">","Ensure the interface exists and its package/name match the namespace exactly (case-sensitive)","If the mapper is XML-only with no interface, you still need a unique non-empty namespace string"],"exampleFix":"<!-- before -->\n<mapper>\n  <select id=\"findById\" resultType=\"User\">...</select>\n</mapper>\n\n<!-- after -->\n<mapper namespace=\"com.acme.UserMapper\">\n  <select id=\"findById\" resultType=\"User\">...</select>\n</mapper>","handlingStrategy":"validation","validationCode":"String ns = mapperRoot.getAttribute(\"namespace\");\nif (ns == null || ns.trim().isEmpty()) throw new IllegalStateException(\"mapper XML missing namespace\");\nif (!ns.matches(\"(?:[a-zA-Z_$][\\\\w$]*\\\\.)+[a-zA-Z_$][\\\\w$]*\")) warn(\"namespace looks unlike an FQCN: \" + ns);","typeGuard":null,"tryCatchPattern":"catch BuilderException at build and surface the resource path; a missing namespace is a build-time fix, not a runtime recovery.","preventionTips":["Generate mapper XML from IDE templates that prefill the namespace","Enforce namespace == mapper interface FQCN in a CI check"],"tags":["mybatis","mapper-xml","namespace"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}