languagetool-org/languagetool · error · RuntimeException

Language was already instantiated, see the cause stacktrace

Error message

Language was already instantiated, see the cause stacktrace below.

What it means

CanadianFrench's constructor guards against duplicate instantiation of the language object. LT requires language classes to be singletons; the constructor stores a stack trace on the first instantiation and throws RuntimeException carrying that trace when a second instance is created.

Source

Thrown at languagetool-language-modules/fr/src/main/java/org/languagetool/language/CanadianFrench.java:32

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package org.languagetool.language;

import java.util.Collections;
import java.util.List;

public class CanadianFrench extends French {

  private static volatile Throwable instantiationTrace;

  public CanadianFrench() {
    super(true);
    Throwable trace = instantiationTrace;
    if (trace != null) {
      throw new RuntimeException("Language was already instantiated, see the cause stacktrace below.", trace);
    }
    instantiationTrace = new Throwable();
  }

  @Override
  public String getName() {
    return "French (Canada)";
  }

  @Override
  public String[] getCountries() {
    return new String[] { "CA" };
  }

  @Override
  public List<String> getDefaultDisabledRulesForVariant() {
    List<String> rules = Collections.singletonList("DOUBLER_UNE_CLASSE");
    return rules;

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Use Languages.getLanguageForShortCode("fr-CA") instead of constructing the object.
  2. Follow the cause stack trace to locate and remove the first (illegal) instantiation path.
  3. Ensure only one classloader loads the French language module.

Example fix

// before
Language lang = new CanadianFrench();
// after
Language lang = Languages.getLanguageForShortCode("fr-CA");
Defensive patterns

Strategy: validation

Validate before calling

// Obtain the singleton instead of constructing:
Language lang = Languages.getLanguageForShortCode("fr-CA");

Try / catch

try {
  new CanadianFrench();
} catch (RuntimeException e) {
  e.getCause().printStackTrace(); // shows first instantiation site
}

Prevention

When it happens

Trigger: Calling new CanadianFrench() directly instead of Languages.getLanguageForShortCode("fr-CA")/getInstance; reflective or framework-driven instantiation; separate classloaders loading the class twice.

Common situations: Hand-written code constructing language instances; DI containers scanning and instantiating Language subclasses; plugin systems with isolated classloaders.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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