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
BelgianFrench's constructor is a debugging guard: Language subclasses may be instantiated only once (LT caches instances via getInstance/languages registry). The constructor records a stack trace on first instantiation and throws RuntimeException with that trace as cause on any second instantiation, exposing who created the duplicate.
Source
Thrown at languagetool-language-modules/fr/src/main/java/org/languagetool/language/BelgianFrench.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 BelgianFrench extends French {
private static volatile Throwable instantiationTrace;
public BelgianFrench() {
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 (Belgium)";
}
@Override
public String[] getCountries() {
return new String[] { "BE" };
}
@Override
public List<String> getDefaultDisabledRulesForVariant() {
List<String> rules = Collections.singletonList("DOUBLER_UNE_CLASSE");
return rules;View on GitHub (pinned to 2e990059ce)
Solutions
- Remove the direct instantiation and use Languages.getLanguageForShortCode("fr-BE") to get the cached instance.
- Inspect the 'cause' stack trace in the exception to find the first instantiation site and eliminate the duplicate path.
- If multiple classloaders are involved, consolidate to a single module/classloader loading languagetool-language-modules/fr.
Example fix
// before
Language lang = new BelgianFrench();
// after
Language lang = Languages.getLanguageForShortCode("fr-BE"); Defensive patterns
Strategy: validation
Validate before calling
// Obtain the singleton instead of constructing:
Language lang = Languages.getLanguageForShortCode("fr-BE"); Try / catch
try {
new BelgianFrench();
} catch (RuntimeException e) {
e.getCause().printStackTrace(); // shows first instantiation site
} Prevention
- Never call 'new' on Language subclasses; always use Languages.getLanguageForShortCode
- Check the cause stack trace to find the duplicate instantiation path
- Avoid multiple classloaders for LanguageTool modules
When it happens
Trigger: Calling new BelgianFrench() directly instead of Languages.getLanguageForShortCode("fr-BE")/its getInstance; reflection, serialization, or subclass instantiation creating a second instance.
Common situations: Application code instantiating language objects manually; multiple classloaders each loading the class; frameworks instantiating the class reflectively; test code constructing the language.
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
- Language was already instantiated, see the cause stacktrace
- 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
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/4fd0a31f8d151045.
Report an issue: GitHub.