languagetool-org/languagetool · error

Could not find month '<monthStr>'

Error message

Could not find month '<monthStr>'

What it means

DateCheckFilter.getMonth() maps Russian month names, inflected forms, abbreviations and Roman numerals (I–XII) to month numbers 1-12. If none of the hardcoded equals comparisons match, it throws this RuntimeException. It signals an unmatched month token in a date recognized by a Russian date rule.

Source

Thrown at languagetool-language-modules/ru/src/main/java/org/languagetool/rules/ru/DateCheckFilter.java:70

  }

  @SuppressWarnings({"ControlFlowStatementWithoutBraces", "MagicNumber"})
  @Override
  protected int getMonth(String monthStr) {
    String mon = monthStr.toLowerCase();
    if (mon.equals("январь") || monthStr.equals("I") || mon.equals("января") || mon.equals("янв")) return 1;
    if (mon.equals("февраль") || monthStr.equals("II") ||  mon.equals("февраля") || mon.equals("фев")) return 2;
    if (mon.equals("март") || monthStr.equals("III") || mon.equals("марта") || mon.equals("мар")) return 3;
    if (mon.equals("апрель") || monthStr.equals("IV") || mon.equals("апреля") || mon.equals("апр")) return 4;
    if (mon.equals("май") || monthStr.equals("V") || mon.equals("мая")) return 5;
    if (mon.equals("июнь") || monthStr.equals("VI") || mon.equals("июня") || mon.equals("ин")) return 6;
    if (mon.equals("июль") || monthStr.equals("VII") || mon.equals("июля") || mon.equals("ил")) return 7;
    if (mon.equals("август") || monthStr.equals("VIII") || mon.equals("августа") || mon.equals("авг")) return 8;
    if (mon.equals("сентябрь") || monthStr.equals("IX") || mon.equals("сентября") || mon.equals("сен")) return 9;
    if (mon.equals("октябрь") || monthStr.equals("X") || mon.equals("октября") || mon.equals("окт")) return 10;
    if (mon.equals("ноябрь") || monthStr.equals("XI") || mon.equals("ноября") || mon.equals("ноя")) return 11;
    if (mon.equals("декабрь") || monthStr.equals("XII") || mon.equals("декабря") || mon.equals("дек")) return 12;
    throw new RuntimeException("Could not find month '" + monthStr + "'");
  }
}

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Add the unmatched token to the if-chain in DateCheckFilter.getMonth (DateCheckFilter.java:70) with the correct month number
  2. Compare the token in the message against the covered strings and note the list mixes equals with full forms plus 'ил'/'сен' style abbreviations — add the missing abbreviation variant consistently for all 12 months
  3. Tighten the corresponding regex rule so only month forms the filter knows about can match
  4. Add a unit test in DateCheckFilterTest covering the new month token

Example fix

// before
if (mon.equals("июль") || monthStr.equals("VII") || mon.equals("июля") || mon.equals("ил")) return 7;
...
throw new RuntimeException("Could not find month '" + monthStr + "'");
// after
if (mon.equals("июль") || monthStr.equals("VII") || mon.equals("июля") || mon.startsWith("июл")) return 7;
...
throw new RuntimeException("Could not find month '" + monthStr + "'");
Defensive patterns

Strategy: validation

Validate before calling

private static final String[] MONTH_PREFIXES = {"январ","феврал","март","апрел","мая","июн","июл","авг","сен","окт","ноя","дек"};
boolean monthSupported(String token) {
  String mon = token.toLowerCase(Locale.ROOT);
  for (String p : MONTH_PREFIXES) if (mon.startsWith(p)) return true;
  return token.matches("(?i)I{1,3}|IV|VI{0,3}|IX|X|XI|XII");
}

Type guard

boolean isRecognizedRussianMonth(String token) {
  return token.toLowerCase(Locale.ROOT).matches("(январ|феврал|март|апрел|ма[йя]|июн|июл|авг|сен|окт|ноя|дек).*")
      || token.matches("[IVX]{1,4}");
}

Try / catch

try {
  result = filter.filter(readings, args);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Could not find month")) {
    log.warn("Skipping date match with unknown month token");
  } else { throw e; }
}

Prevention

When it happens

Trigger: A Russian date rule matched a month token not covered by the list, e.g. an uncommon abbreviation ('июл' vs 'ил' inconsistency in the source), an inflected form ('июля' is covered but e.g. 'июлем' is not), a lowercase/uppercase variant mismatch, or a Roman numeral outside the covered set.

Common situations: Extending Russian date regexes in the ru module without syncing getMonth; test data or user text with unusual month inflections or abbreviations; typos ('ияюнь'); locale-dependent display names fed back into the parser.

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/94f7f75619932530. Report an issue: GitHub.