languagetool-org/languagetool · error · RuntimeException
Directory must contain at least '1grams', '2grams', and '3gr
Error message
Directory must contain at least '1grams', '2grams', and '3grams': ${topIndexDir.getAbsolutePath()} What it means
LuceneSingleIndexLanguageModel validates that the ngram index directory contains subdirectories named '1grams', '2grams', '3grams'. If the top directory contains none of these, validateDirectory throws RuntimeException naming the path.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/languagemodel/LuceneSingleIndexLanguageModel.java:69
* Throw RuntimeException is the given directory does not seem to be a valid ngram top directory
* with sub directories {@code 1grams} etc.
* @since 3.0
*/
public static void validateDirectory(File topIndexDir) {
if (!topIndexDir.exists() || !topIndexDir.isDirectory()) {
throw new RuntimeException("Not found or is not a directory:\n" +
topIndexDir + "\n" +
"As ngram directory, please select the directory that has a subdirectory like 'en'\n" +
"(or whatever language code you're using).");
}
List<String> dirs = new ArrayList<>();
for (String name : topIndexDir.list()) {
if (name.matches("[123]grams")) {
dirs.add(name);
}
}
if (dirs.isEmpty()) {
throw new RuntimeException("Directory must contain at least '1grams', '2grams', and '3grams': " + topIndexDir.getAbsolutePath());
}
if (dirs.size() < 3) {
throw new RuntimeException("Expected at least '1grams', '2grams', and '3grams' sub directories but only got " + dirs + " in " + topIndexDir.getAbsolutePath());
}
}
/**
* Only used internally.
* @since 3.2
*/
@Experimental
public static void clearCaches() {
dirToSearcherMap.clear();
}
/**
* @param topIndexDir a directory which contains at least another sub directory called {@code 3grams},
* which is a Lucene index with ngram occurrences as created byView on GitHub (pinned to 2e990059ce)
Solutions
- Verify the path points to the directory directly containing 1grams/, 2grams/, 3grams/
- Fix the configuration so it references the extracted ngram index directory
- Download/extract the correct language ngram index from LanguageTool
Example fix
// before
LanguageModel lm = new LuceneSingleIndexLanguageModel(new File("/data")); // /data lacks *grams
// after
LanguageModel lm = new LuceneSingleIndexLanguageModel(new File("/data/en/ngrams")); // contains 1grams..3grams Defensive patterns
Strategy: validation
Validate before calling
File[] subs = ngramDir.listFiles(File::isDirectory);
Set<String> names = Arrays.stream(subs).map(File::getName).collect(Collectors.toSet());
if (!names.containsAll(Set.of("1grams","2grams","3grams"))) throw new IllegalStateException("Ngram index incomplete: " + ngramDir); Try / catch
try { model = new LuceneSingleIndexLanguageModel(ngramDir); } catch (RuntimeException e) { if (e.getMessage().contains("grams")) { /* fix path or re-extract data */ } throw e; } Prevention
- Verify the directory contains 1grams/, 2grams/, 3grams/ at startup, before use
- Extract the official ngram archive fully and point config at the exact extraction dir
- Add a health check that constructs the model early so bad paths fail fast
When it happens
Trigger: Constructing a LuceneSingleIndexLanguageModel (which calls doValidateDirectory) pointing at a directory that contains no ngram subdirectories at all — empty dir, wrong dir, or an index not yet unpacked.
Common situations: Pointing the ngram data path at the parent directory of the index, a typo in the configured path, or the ngram archive extracted to a nested folder so the *grams dirs aren't at the top level.
Related errors
- Expected at least '1grams', '2grams', and '3grams' sub direc
- No directories '1grams' ... '3grams' found in ${topIndexDir}
- Requested ${tokens.size()}gram but index has only up to ${ma
- Expected 'totalTokenCount' meta documents not found in 1gram
- grams must be between 1 and 5:
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/688ac76d5e1dc110.
Report an issue: GitHub.