languagetool-org/languagetool · error · RuntimeException
No ${ngramSize}grams directory found in ${topIndexDir}
Error message
No ${ngramSize}grams directory found in ${topIndexDir} What it means
getLuceneSearcher(ngramSize) looks up a pre-loaded LuceneSearcher for the requested ngram size in luceneSearcherMap. If no searcher was registered for that size (because no '<n>grams' directory exists under the top index directory), it throws. This typically means the index layout on disk does not match what the model was configured to load.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/languagemodel/LuceneSingleIndexLanguageModel.java:173
for (ScoreDoc scoreDoc : docs.scoreDocs) {
long tmp = Long.parseLong(luceneSearcher.reader.document(scoreDoc.doc).get("totalTokenCount"));
if (tmp > result) {
// due to the way FrequencyIndexCreator adds these totalTokenCount fields, we must not sum them,
// but take the largest one:
result = tmp;
}
}
return result;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
protected LuceneSearcher getLuceneSearcher(int ngramSize) {
LuceneSearcher luceneSearcher = luceneSearcherMap.get(ngramSize);
if (luceneSearcher == null) {
throw new RuntimeException("No " + ngramSize + "grams directory found in " + topIndexDir);
}
return luceneSearcher;
}
private LuceneSearcher getCachedLuceneSearcher(File indexDir) {
LuceneSearcher luceneSearcher = dirToSearcherMap.get(indexDir);
if (luceneSearcher == null) {
try {
LuceneSearcher newSearcher = new LuceneSearcher(indexDir);
dirToSearcherMap.put(indexDir, newSearcher);
return newSearcher;
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
return luceneSearcher;
}
}View on GitHub (pinned to 2e990059ce)
Solutions
- Download/use the full ngram index for the language that includes all needed '<n>grams' directories (1grams, 2grams, 3grams).
- Verify the top index directory contains subdirectories literally named '<n>grams' (e.g. '3grams', not '3-grams' or 'trigrams').
- Check extraction of the index archive completed (no truncated/missing subdirectories).
- Match the index release to your LanguageTool version; older indexes may have different layouts.
Example fix
// before: only 1grams/2grams present $ ls /data/ngrams/en -> 1grams 2grams // after: fetch full index $ ls /data/ngrams/en -> 1grams 2grams 3grams
Defensive patterns
Strategy: validation
Validate before calling
for (int n : new int[]{1,2,3}) {
File d = new File(topIndexDir, n + "grams");
if (!d.isDirectory()) throw new IllegalStateException("Missing " + d);
} Prevention
- Check '<n>grams' subdirectories exist before constructing the model
- Fully extract the index archive before use
- Match index release to LanguageTool version
When it happens
Trigger: Calling getCount() (or anything resolving a searcher) with an ngram size whose '<n>grams' directory was not found or not registered when the model scanned topIndexDir; e.g. requesting trigram lookups when only 1grams/2grams directories exist.
Common situations: Downloading an index that ships only 1grams/2grams but running rules that need 3grams; mistyping/misplacing directories so names don't match the expected '<n>grams' pattern; incomplete archive extraction.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Did not expect more than 1000 'totalTokenCount' meta documen
- More than 2000 matches for '${term}' not supported for perfo
- Directory must contain at least '1grams', '2grams', and '3gr
- Expected at least '1grams', '2grams', and '3grams' sub direc
- No directories '1grams' ... '3grams' found in ${topIndexDir}
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/480df0722fba0550.
Report an issue: GitHub.