languagetool-org/languagetool · error · RuntimeException

French(Premium) language expected, got " + language

Error message

French(Premium) language expected, got " + language

What it means

French.getInstance() resolves the language for the French short code and asserts it is an instance of French. In the premium build the short code maps to FrenchPremium (a subclass), so the instanceof check accepts it; if Languages returns any other Language implementation, the invariant is broken and RuntimeException is thrown.

Source

Thrown at languagetool-language-modules/fr/src/main/java/org/languagetool/language/French.java:599

    if (enabledRules != null && enabledRules.contains("APOS_TYP")) {
      List<String> newReplacements = new ArrayList<>();
      for (String s : rm.getSuggestedReplacements()) {
        if (s.length() > 1) {
          s = s.replace('\'', '’');
        }
        newReplacements.add(s);
      }
      rm.setSuggestedReplacements(newReplacements);
    }
    return rm;
  }

  public static @NotNull French getInstance() {
    Language language = Objects.requireNonNull(Languages.getLanguageForShortCode(FRENCH_SHORT_CODE));
    if (language instanceof French french) { // cannot use French here as in premium FRENCH_SHORT_CODE returns FrenchPremium
      return french;
    }
    throw new RuntimeException("French(Premium) language expected, got " + language);
  }
}

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Check the 'got <language>' value in the message to see which class was registered for 'fr'.
  2. Remove/rename any custom Language registered under the 'fr' short code.
  3. Clean the classpath of duplicate/mixed languagetool-language-modules jars (standard vs premium).

Example fix

// before (custom registration hijacks the code)
Languages.addLanguage(new MyFrenchVariant()); // short code "fr"
// after
Languages.addLanguage(new MyFrenchVariant()); // short code "fr-XX"
Defensive patterns

Strategy: validation

Validate before calling

Language l = Languages.getLanguageForShortCode("fr");
if (!(l instanceof French)) {
  throw new IllegalStateException("'fr' is bound to " + l.getClass() + ", not French/FrenchPremium");
}

Type guard

boolean isFrench(Language l) { return l instanceof French; }

Try / catch

try {
  French french = French.getInstance();
} catch (RuntimeException e) {
  LOG.error("'fr' short code bound to unexpected language: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling French.getInstance() when the language registry contains a non-French implementation for 'fr' — e.g. a custom Language registered under the 'fr' short code, or a classpath mixing language modules so the registry resolution is unexpected.

Common situations: Registering a custom French-like language with short code 'fr'; shading/repackaging LanguageTool classes so Languages.getLanguageForShortCode returns an unexpected class; premium vs standard module conflicts on the classpath.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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