{"record":{"id":"ca2f5a97c012a208","repo":"MyCATApache/Mycat-Server","slug":"can-t-find-function-of-name-funname","errorCode":null,"errorMessage":"can't find function of name :${funName}","messagePattern":"can't find function of name :(.+?)","errorType":"exception","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/config/loader/xml/XMLRuleLoader.java","lineNumber":150,"sourceCode":"\t\t\t\tif (tableRules.containsKey(name)) {\r\n\t\t\t\t\tthrow new ConfigException(\"table rule \" + name\r\n\t\t\t\t\t\t\t+ \" duplicated!\");\r\n\t\t\t\t}\r\n\t\t\t\t//获取rule标签\r\n\t\t\t\tNodeList ruleNodes = e.getElementsByTagName(\"rule\");\r\n\t\t\t\tint length = ruleNodes.getLength();\r\n\t\t\t\tif (length > 1) {\r\n\t\t\t\t\tthrow new ConfigException(\"only one rule can defined :\"\r\n\t\t\t\t\t\t\t+ name);\r\n\t\t\t\t}\r\n\t\t\t\t//目前只处理第一个，未来可能有多列复合逻辑需求\r\n\t\t\t\t//RuleConfig是保存着rule与function对应关系的对象\r\n\t\t\t\tRuleConfig rule = loadRule((Element) ruleNodes.item(0));\r\n\t\t\t\tString funName = rule.getFunctionName();\r\n\t\t\t\t//判断function是否存在，获取function\r\n\t\t\t\tAbstractPartitionAlgorithm func = functions.get(funName);\r\n\t\t\t\tif (func == null) {\r\n\t\t\t\t\tthrow new ConfigException(\"can't find function of name :\"\r\n\t\t\t\t\t\t\t+ funName);\r\n\t\t\t\t}\r\n\t\t\t\trule.setRuleAlgorithm(func);\r\n\t\t\t\t//保存到tableRules\r\n\t\t\t\ttableRules.put(name, new TableRuleConfig(name, rule));\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate RuleConfig loadRule(Element element) throws SQLSyntaxErrorException {\r\n\t\t//读取columns\r\n\t\tElement columnsEle = ConfigUtil.loadElement(element, \"columns\");\r\n\t\tString column = columnsEle.getTextContent();\r\n\t\tString[] columns = SplitUtil.split(column, ',', true);\r\n\t\tif (columns.length > 1) {\r\n\t\t\tthrow new ConfigException(\"table rule coulmns has multi values:\"\r\n\t\t\t\t\t+ columnsEle.getTextContent());\r\n\t\t}\r","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/config/loader/xml/XMLRuleLoader.java#L132-L168","documentation":"Each tableRule's <algorithm> element names a sharding function declared in a <function> block. loadTableRules looks the function name up in the functions map; if absent, it throws this ConfigException. This means the rule references a function that was never defined (or failed to load) in rule.xml.","triggerScenarios":"rule.xml <tableRule> whose <algorithm>foo</algorithm> has no matching <function name=\"foo\" ...> block; also produced when the algorithm name is misspelled or case-mismatched, or when loadFunctions failed earlier so the function map is incomplete.","commonSituations":"Copying a tableRule from a sample but forgetting to copy its function definition; typos in the algorithm name; XML validation ordering issues where the function block was deleted during cleanup.","solutions":["Add the missing <function name=\"...\" class=\"...\"> block to rule.xml, matching the tableRule's algorithm value exactly.","Check spelling/case of the algorithm name against the function's name attribute.","Scan the log for an earlier createFunction/reflection error indicating the function block failed to load."],"exampleFix":"// before (rule.xml)\n<tableRule name=\"order-rule\">\n  <rule><columns>id</columns><algorithm>mod-long</algorithm></rule>\n</tableRule>\n<!-- <function name=\"mod-long\" .../> missing -->\n// after\n<tableRule name=\"order-rule\">\n  <rule><columns>id</columns><algorithm>mod-long</algorithm></rule>\n</tableRule>\n<function name=\"mod-long\" class=\"io.mycat.route.function.PartitionByMod\">\n  <property name=\"count\">4</property>\n</function>","handlingStrategy":"validation","validationCode":"// Verify every tableRule algorithm references a defined function name\nSet<String> fnNames = new HashSet<>();\nNodeList fns = doc.getElementsByTagName(\"function\");\nfor (int i = 0; i < fns.getLength(); i++)\n    fnNames.add(((Element) fns.item(i)).getAttribute(\"name\"));\nNodeList rules = doc.getElementsByTagName(\"tableRule\");\nfor (int i = 0; i < rules.getLength(); i++) {\n    Element tr = (Element) rules.item(i);\n    String algo = ((Element) tr.getElementsByTagName(\"rule\").item(0))\n        .getElementsByTagName(\"algorithm\").item(0).getTextContent().trim();\n    if (!fnNames.contains(algo))\n        throw new IllegalStateException(\"algorithm \" + algo + \" has no <function> definition\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ruleLoader.load();\n} catch (ConfigException e) {\n    if (e.getMessage().startsWith(\"can't find function of name\")) {\n        LOG.error(\"Missing <function> block in rule.xml: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Always copy a tableRule together with its function definition.","Keep algorithm names in a checked list; avoid free-typing them.","Run a pre-deploy cross-reference check between tableRule algorithms and function names."],"tags":["configuration","xml","missing-reference","sharding"],"backgroundTag":"missing-required-config-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"}