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
Chinese is a singleton-style Language class that guards against multiple instantiation by recording a Throwable on first construction; a second constructor call throws this RuntimeException, with the first instantiation's stacktrace as the cause. This protects internal caching assumptions that Language objects are created once.
Source
Thrown at languagetool-language-modules/zh/src/main/java/org/languagetool/language/Chinese.java:49
import org.languagetool.tagging.Tagger;
import org.languagetool.tagging.zh.ChineseTagger;
import org.languagetool.tokenizers.SentenceTokenizer;
import org.languagetool.tokenizers.Tokenizer;
import org.languagetool.tokenizers.zh.ChineseSentenceTokenizer;
import org.languagetool.tokenizers.zh.ChineseWordTokenizer;
import java.io.IOException;
import java.util.*;
public class Chinese extends LanguageWithModel {
private static final String LANGUAGE_SHORT_CODE = "zh-CN";
private static volatile Throwable instantiationTrace;
public Chinese() {
Throwable trace = instantiationTrace;
if (trace != null) {
throw new RuntimeException("Language was already instantiated, see the cause stacktrace below.", trace);
}
instantiationTrace = new Throwable();
}
/**
* This is a fake constructor overload for the subclasses. Public constructors can only be used by the LT itself.
*/
protected Chinese(boolean fakeValue) {
}
@Override
public String getShortCode() {
return "zh";
}
@Override
public String getName() {View on GitHub (pinned to 2e990059ce)
Solutions
- Use Languages.getLanguageForShortCode("zh") or Chinese.getInstance() instead of new Chinese()
- Inspect the cause stacktrace to find where the first instantiation happened
- Remove any custom factory code that constructs Chinese directly
Example fix
// before
Language zh = new Chinese();
// after
Language zh = Languages.getLanguageForShortCode("zh"); Defensive patterns
Strategy: type-guard
Validate before calling
Language lang = Languages.getLanguageForShortCode("zh");
if (lang instanceof Chinese) { /* reuse it */ } Type guard
boolean chineseReady() {
return Languages.getLanguageForShortCode("zh") instanceof Chinese;
} Try / catch
try {
Language zh = getOrCreateChinese();
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Language was already instantiated")) {
zh = Languages.getLanguageForShortCode("zh"); // reuse singleton
} else throw e;
} Prevention
- Never construct Language subclasses directly; use the Languages registry
- Use Chinese.getInstance() as the single access point
- Read the cause stacktrace to find the first instantiation site
- Keep custom factories in sync with LanguageTool's registration
When it happens
Trigger: Calling new Chinese() a second time, e.g. code instantiating the language directly instead of using Languages.getLanguageForShortCode("zh"), or reflection/plugin code re-creating it.
Common situations: Custom server setups or tests that construct Chinese manually after LanguageTool has already registered it; copying instantiation patterns from other language classes.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Language was already instantiated, see the cause stacktrace
- Language was already instantiated, see the cause stacktrace
- Language was already instantiated, see the cause stacktrace
- French(Premium) language expected, got " + language
- Language was already instantiated, see the cause stacktrace
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/74a830e9ae3af161.
Report an issue: GitHub.