{"record":{"id":"0f267205519dc25a","repo":"MyCATApache/Mycat-Server","slug":"datanode-dnnamepre-define-error-attribute-can","errorCode":null,"errorMessage":"dataNode ${dnNamePre} define error ,attribute can't be empty","messagePattern":"dataNode (.+?) define error ,attribute can't be empty","errorType":"exception","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java","lineNumber":623,"sourceCode":"                                String.valueOf(tableConf.getRule().getRuleAlgorithm().getPartitionNum()),\n                                String.valueOf(tableConf.getDataNodes().size())\n                        });\n                break;\n        }\n    }\n\n    private void loadDataNodes(Element root) {\n        //读取DataNode分支\n        NodeList list = root.getElementsByTagName(\"dataNode\");\n        for (int i = 0, n = list.getLength(); i < n; i++) {\n            Element element = (Element) list.item(i);\n            String dnNamePre = element.getAttribute(\"name\");\n\n            String databaseStr = element.getAttribute(\"database\");\n            String host = element.getAttribute(\"dataHost\");\n            //字符串不为空\n            if (empty(dnNamePre) || empty(databaseStr) || empty(host)) {\n                throw new ConfigException(\"dataNode \" + dnNamePre + \" define error ,attribute can't be empty\");\n            }\n            //dnNames（name）,databases（database）,hostStrings（dataHost）都可以配置多个，以',', '$', '-'区分，但是需要保证database的个数*dataHost的个数=name的个数\n            //多个dataHost与多个database如果写在一个标签，则每个dataHost拥有所有database\n            //例如：<dataNode name=\"dn1$0-75\" dataHost=\"localhost$1-10\" database=\"db$0-759\" />\n            //则为：localhost1拥有dn1$0-75,localhost2也拥有dn1$0-75（对应db$76-151）\n            String[] dnNames = io.mycat.util.SplitUtil.split(dnNamePre, ',', '$', '-');\n            String[] databases = io.mycat.util.SplitUtil.split(databaseStr, ',', '$', '-');\n            String[] hostStrings = io.mycat.util.SplitUtil.split(host, ',', '$', '-');\n\n            if (dnNames.length > 1 && dnNames.length != databases.length * hostStrings.length) {\n                throw new ConfigException(\"dataNode \" + dnNamePre\n                        + \" define error ,dnNames.length must be=databases.length*hostStrings.length\");\n            }\n            if (dnNames.length > 1) {\n\n                List<String[]> mhdList = mergerHostDatabase(hostStrings, databases);\n                for (int k = 0; k < dnNames.length; k++) {\n                    String[] hd = mhdList.get(k);","sourceCodeStart":605,"sourceCodeEnd":641,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java#L605-L641","documentation":"Thrown by XMLSchemaLoader when parsing a <dataNode> element whose required attributes (name, database, or dataHost) are missing or empty. Each dataNode must identify a name, a physical database, and a dataHost to be usable.","triggerScenarios":"A <dataNode database=\"db1\" dataHost=\"host1\" /> without name, or name present but database/dataHost attribute empty, in schema.xml.","commonSituations":"Hand-edited or generated schema.xml dropping an attribute; XML templates with unfilled placeholders (name=\"\"); copy-paste errors creating incomplete dataNode entries.","solutions":["Add non-empty name, database, and dataHost attributes to the offending <dataNode> element in schema.xml","Validate the XML against the expected dataNode structure before startup","Check for template placeholders that were never substituted"],"exampleFix":"// before (schema.xml)\n<dataNode name=\"dn1\" database=\"\" dataHost=\"localhost1\" />\n// after\n<dataNode name=\"dn1\" dataHost=\"localhost1\" database=\"db1\" />","handlingStrategy":"validation","validationCode":"// ensure dataNode elements have all required attributes\nfor (Element dn : dataNodeElements(\"schema.xml\")) {\n    for (String attr : new String[]{\"name\", \"database\", \"dataHost\"}) {\n        if (dn.getAttribute(attr).trim().isEmpty())\n            throw new IllegalStateException(\"<dataNode> missing attribute: \" + attr);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    configLoader.load();\n} catch (ConfigException e) {\n    if (e.getMessage().contains(\"define error ,attribute can't be empty\")) {\n        String name = extractBetween(e.getMessage(), \"dataNode \", \" define error\");\n        log.error(\"<dataNode name='\" + name + \"'> is missing name/database/dataHost\", e);\n    }\n    throw e;\n}","preventionTips":["Use a checklist (name, database, dataHost) when authoring <dataNode> entries","Validate generated XML against a schema before shipping; catch unfilled template placeholders","Review dataNode blocks as whole units to avoid partial edits"],"tags":["config","xml","empty-attribute","datanode"],"backgroundTag":"empty-required-field","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}