{"record":{"id":"ca149407f9017d08","repo":"elastic/elasticsearch","slug":"invalid-mapping-rule-rule","errorCode":null,"errorMessage":"Invalid Mapping Rule : [{rule}]","messagePattern":"Invalid Mapping Rule : \\[(.+?)\\]","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"modules/analysis-common/src/main/java/org/elasticsearch/analysis/common/WordDelimiterTokenFilterFactory.java","lineNumber":117,"sourceCode":"    public static int getFlag(int flag, Settings settings, String key, boolean defaultValue) {\n        if (settings.getAsBoolean(key, defaultValue)) {\n            return flag;\n        }\n        return 0;\n    }\n\n    // source => type\n    private static final Pattern typePattern = Pattern.compile(\"(.*)\\\\s*=>\\\\s*(.*)\\\\s*$\");\n\n    /**\n     * parses a list of MappingCharFilter style rules into a custom byte[] type table\n     */\n    static byte[] parseTypes(Collection<String> rules) {\n        SortedMap<Character, Byte> typeMap = new TreeMap<>();\n        for (String rule : rules) {\n            Matcher m = typePattern.matcher(rule);\n            if (m.find() == false) {\n                throw new RuntimeException(\"Invalid Mapping Rule : [\" + rule + \"]\");\n            }\n            String lhs = parseString(m.group(1).trim());\n            Byte rhs = parseType(m.group(2).trim());\n            if (lhs.length() != 1) throw new RuntimeException(\"Invalid Mapping Rule : [\" + rule + \"]. Only a single character is allowed.\");\n            if (rhs == null) throw new RuntimeException(\"Invalid Mapping Rule : [\" + rule + \"]. Illegal type.\");\n            typeMap.put(lhs.charAt(0), rhs);\n        }\n\n        // ensure the table is always at least as big as DEFAULT_WORD_DELIM_TABLE for performance\n        byte types[] = new byte[Math.max(typeMap.lastKey() + 1, WordDelimiterIterator.DEFAULT_WORD_DELIM_TABLE.length)];\n        for (int i = 0; i < types.length; i++) {\n            types[i] = WordDelimiterIterator.getType(i);\n        }\n        for (Map.Entry<Character, Byte> mapping : typeMap.entrySet()) {\n            types[mapping.getKey()] = mapping.getValue();\n        }\n        return types;\n    }","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/analysis-common/src/main/java/org/elasticsearch/analysis/common/WordDelimiterTokenFilterFactory.java#L99-L135","documentation":"WordDelimiterTokenFilterFactory.parseTypes converts each 'type_table' entry into a char->type mapping. Every rule must match the regex '(.*)\\s*=>\\s*(.*)\\s*$' (i.e. 'lhs => rhs'). If Matcher.find() returns false, parseTypes throws RuntimeException (not IllegalArgumentException) with the offending rule. This indicates a structural problem — the rule lacks the '=>' separator at all.","triggerScenarios":"Passing a type_table entry on a word_delimiter filter that does not contain '=>', e.g. \"LOWER\", \"a,b,c\", or a stray comment line.","commonSituations":"Hand-editing a type_table and forgetting the arrow; mis-pasting from documentation that used a different separator; carrying over an old Solr config with a different rule format.","solutions":["Reformat every type_table entry as \"<chars> => <TYPE>\" with a literal '=>'.","Strip comment lines and stray punctuation from the list.","Re-run the index/template create."],"exampleFix":"// before\n\"type_table\": [\"LOWER\", \"- => ALPHA\"]\n// after\n\"type_table\": [\"- => ALPHA\", \". => DIGIT\"]","handlingStrategy":"validation","validationCode":"// Every type_table entry must match 'lhs => rhs'\nstatic final java.util.regex.Pattern RULE = java.util.regex.Pattern.compile(\"(.*)\\\\s*=>\\\\s*(.*)\\\\s*$\");\nstatic List<String> badRules(List<String> typeTable) {\n  return typeTable.stream().filter(r -> !RULE.matcher(r).find()).toList();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint type_table entries against the 'lhs => rhs' regex before applying.","Keep type_table under version control and re-validate on every change."],"tags":["analysis","word-delimiter","type-table","parsing"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}