languagetool-org/languagetool · error · RuntimeException

Could not find month '<monthStr>'

Error message

Could not find month '<monthStr>'

What it means

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.

Source

Thrown at languagetool-language-modules/ru/src/main/java/org/languagetool/rules/ru/DateFilterHelper.java:74

  }

  @SuppressWarnings({"ControlFlowStatementWithoutBraces", "MagicNumber"})
  protected int getMonth(String monthStr) {
    String mon = StringTools.trimSpecialCharacters(monthStr).toLowerCase();
    if (mon.startsWith("янв")) return 1;
    if (mon.startsWith("фев")) return 2;
    if (mon.startsWith("мар")) return 3;
    if (mon.startsWith("апр")) return 4;
    if (mon.startsWith("май")) return 5;
    if (mon.startsWith("мая")) return 5; //
    if (mon.startsWith("июн")) return 6;
    if (mon.startsWith("июл")) return 7;
    if (mon.startsWith("авг")) return 8;
    if (mon.startsWith("сен")) return 9;
    if (mon.startsWith("окт")) return 10;
    if (mon.startsWith("ноя")) return 11;
    if (mon.startsWith("дек")) return 12;
    throw new RuntimeException("Could not find month '" + monthStr + "'");
  }
}

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Add the unmatched prefix to DateFilterHelper.getMonth (DateFilterHelper.java:74) with the correct month number
  2. Diff this method against DateCheckFilter.getMonth and unify coverage for all 12 months and Roman numerals
  3. Constrain the regex rule so only supported month forms can reach the filter
  4. Add a unit test for the failing token

Example fix

// before
if (mon.startsWith("дек")) return 12;
throw new RuntimeException("Could not find month '" + monthStr + "'");
// after
if (mon.startsWith("дек")) return 12;
if (mon.startsWith("май") || mon.startsWith("ма")) return 5;
throw new RuntimeException("Could not find month '" + monthStr + "'");
Defensive patterns

Strategy: validation

Validate before calling

String[] monthPrefixes = {"январ","феврал","март","апрел","ма","июн","июл","авг","сен","окт","ноя","дек"};
boolean monthSupported(String token) {
  String m = token.toLowerCase(Locale.ROOT);
  return Arrays.stream(monthPrefixes).anyMatch(m::startsWith) || m.matches("[IVXivx]+");
}

Type guard

boolean isParsableRussianMonth(String token) {
  String m = token.toLowerCase(Locale.ROOT);
  return m.matches("(январ|феврал|март|апрел|ма|июн|июл|авг|сен|окт|ноя|дек).*") || m.matches("[ivx]+");
}

Try / catch

try {
  analyzed = helper.filter(tokens, arguments);
} catch (RuntimeException e) {
  if (String.valueOf(e.getMessage()).startsWith("Could not find month")) {
    log.warn("Unknown month token in date: {}", e.getMessage());
    return Collections.emptyList();
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/bde8bf001b961188. Report an issue: GitHub.