languagetool-org/languagetool · error · RuntimeException
No directories '1grams' ... '3grams' found in ${topIndexDir}
Error message
No directories '1grams' ... '3grams' found in ${topIndexDir} What it means
After adding indexes for ngram sizes 1-4, the LuceneSingleIndexLanguageModel constructor checks whether any searcher was actually registered. If luceneSearcherMap is empty — no *grams directory existed — it throws RuntimeException.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/languagemodel/LuceneSingleIndexLanguageModel.java:98
@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 by
* {@code org.languagetool.dev.FrequencyIndexCreator}.
*/
public LuceneSingleIndexLanguageModel(File topIndexDir) {
doValidateDirectory(topIndexDir);
this.topIndexDir = topIndexDir;
addIndex(topIndexDir, 1);
addIndex(topIndexDir, 2);
addIndex(topIndexDir, 3);
addIndex(topIndexDir, 4);
if (luceneSearcherMap.isEmpty()) {
throw new RuntimeException("No directories '1grams' ... '3grams' found in " + topIndexDir);
}
maxNgram = Collections.<Integer>max(luceneSearcherMap.keySet());
}
public LuceneSingleIndexLanguageModel(int maxNgram) {
this.maxNgram = maxNgram;
this.topIndexDir = null;
}
protected void doValidateDirectory(File topIndexDir) {
validateDirectory(topIndexDir);
}
private void addIndex(File topIndexDir, int ngramSize) {
File indexDir = new File(topIndexDir, ngramSize + "grams");
if (indexDir.exists() && indexDir.isDirectory()) {
if (luceneSearcherMap.containsKey(ngramSize)) {
throw new RuntimeException("Searcher for ngram size " + ngramSize + " already exists");View on GitHub (pinned to 2e990059ce)
Solutions
- Point the constructor at the directory containing the extracted 1grams...3grams subdirectories
- Extract the ngram data archive to the configured location
- Verify with ls that *grams directories exist before constructing
Example fix
// before
new LuceneSingleIndexLanguageModel(new File("/data/empty"));
// after
new LuceneSingleIndexLanguageModel(new File("/data/en")); // has 1grams..3grams Defensive patterns
Strategy: validation
Validate before calling
if (ngramDir == null || !ngramDir.isDirectory()) throw new IllegalStateException("Not a directory: " + ngramDir);
boolean any = Arrays.stream(ngramDir.list()).anyMatch(n -> n.matches("[1-4]grams"));
if (!any) throw new IllegalStateException("No ngram subdirectories in " + ngramDir); Try / catch
try { model = new LuceneSingleIndexLanguageModel(ngramDir); } catch (RuntimeException e) { if (e.getMessage().startsWith("No directories")) { /* point to correct index dir */ } throw e; } Prevention
- Ensure the ngram data archive is extracted before service startup
- Log the resolved absolute index path on startup for easy debugging
- Fail fast at boot with a directory check rather than lazily on first use
When it happens
Trigger: Instantiating LuceneSingleIndexLanguageModel(File topIndexDir) where topIndexDir exists but contains no 1grams/2grams/3grams/4grams directories (e.g. without the validateDirectory path having rejected it first).
Common situations: Same wrong-path problems as the validation errors: empty directory, data not yet extracted, path typo; differs from [34]/[35] only in the constructor variant used.
Related errors
- Directory must contain at least '1grams', '2grams', and '3gr
- Expected at least '1grams', '2grams', and '3grams' sub direc
- 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/821b67ed6bcb9cfb.
Report an issue: GitHub.