{"record":{"id":"bde8bf001b961188","repo":"languagetool-org/languagetool","slug":"could-not-find-month-monthstr-bde8bf","errorCode":null,"errorMessage":"Could not find month '<monthStr>'","messagePattern":"Could not find month '<monthStr>'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-language-modules/ru/src/main/java/org/languagetool/rules/ru/DateFilterHelper.java","lineNumber":74,"sourceCode":"  }\n\n  @SuppressWarnings({\"ControlFlowStatementWithoutBraces\", \"MagicNumber\"})\n  protected int getMonth(String monthStr) {\n    String mon = StringTools.trimSpecialCharacters(monthStr).toLowerCase();\n    if (mon.startsWith(\"янв\")) return 1;\n    if (mon.startsWith(\"фев\")) return 2;\n    if (mon.startsWith(\"мар\")) return 3;\n    if (mon.startsWith(\"апр\")) return 4;\n    if (mon.startsWith(\"май\")) return 5;\n    if (mon.startsWith(\"мая\")) return 5; //\n    if (mon.startsWith(\"июн\")) return 6;\n    if (mon.startsWith(\"июл\")) return 7;\n    if (mon.startsWith(\"авг\")) return 8;\n    if (mon.startsWith(\"сен\")) return 9;\n    if (mon.startsWith(\"окт\")) return 10;\n    if (mon.startsWith(\"ноя\")) return 11;\n    if (mon.startsWith(\"дек\")) return 12;\n    throw new RuntimeException(\"Could not find month '\" + monthStr + \"'\");\n  }\n}\n\n","sourceCodeStart":56,"sourceCodeEnd":78,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-language-modules/ru/src/main/java/org/languagetool/rules/ru/DateFilterHelper.java#L56-L78","documentation":"DateFilterHelper.getMonth() maps Russian month tokens to month numbers via startsWith checks for January through December plus Roman numeral handling. If a month token matches none of the prefixes, this RuntimeException is thrown. It indicates a month form produced by a date rule that the helper cannot interpret.","triggerScenarios":"A matched month token whose prefix is missing, e.g. an abbreviation style not covered ('июль' would match 'июл', but forms like 'мае/мая' for May if the май branch is absent or too narrow), Roman numerals outside the covered set, or case/whitespace anomalies in the token.","commonSituations":"Adding new Russian relative-date regexes without updating this helper; keeping DateCheckFilter.getMonth and DateFilterHelper.getMonth in sync manually; test sentences with rare month inflections ('сентябрём'); localized month names generated by a different Locale not matching the hardcoded Cyrillic strings.","solutions":["Add the unmatched prefix to DateFilterHelper.getMonth (DateFilterHelper.java:74) with the correct month number","Diff this method against DateCheckFilter.getMonth and unify coverage for all 12 months and Roman numerals","Constrain the regex rule so only supported month forms can reach the filter","Add a unit test for the failing token"],"exampleFix":"// before\nif (mon.startsWith(\"дек\")) return 12;\nthrow new RuntimeException(\"Could not find month '\" + monthStr + \"'\");\n// after\nif (mon.startsWith(\"дек\")) return 12;\nif (mon.startsWith(\"май\") || mon.startsWith(\"ма\")) return 5;\nthrow new RuntimeException(\"Could not find month '\" + monthStr + \"'\");","handlingStrategy":"validation","validationCode":"String[] monthPrefixes = {\"январ\",\"феврал\",\"март\",\"апрел\",\"ма\",\"июн\",\"июл\",\"авг\",\"сен\",\"окт\",\"ноя\",\"дек\"};\nboolean monthSupported(String token) {\n  String m = token.toLowerCase(Locale.ROOT);\n  return Arrays.stream(monthPrefixes).anyMatch(m::startsWith) || m.matches(\"[IVXivx]+\");\n}","typeGuard":"boolean isParsableRussianMonth(String token) {\n  String m = token.toLowerCase(Locale.ROOT);\n  return m.matches(\"(январ|феврал|март|апрел|ма|июн|июл|авг|сен|окт|ноя|дек).*\") || m.matches(\"[ivx]+\");\n}","tryCatchPattern":"try {\n  analyzed = helper.filter(tokens, arguments);\n} catch (RuntimeException e) {\n  if (String.valueOf(e.getMessage()).startsWith(\"Could not find month\")) {\n    log.warn(\"Unknown month token in date: {}\", e.getMessage());\n    return Collections.emptyList();\n  }\n  throw e;\n}","preventionTips":["Keep DateFilterHelper.getMonth and DateCheckFilter.getMonth feature-identical","Roman-numeral tokens must match the exact set the method handles","Unit-test all 12 months plus abbreviations after any regex change","Normalize case and trim tokens before they reach the filter"],"tags":["java","russian","nlp","date-parsing","languagetool"],"backgroundTag":"invalid-enum-value","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}