languagetool-org/languagetool · error
not found - make sure files are names *.old and *.new in mu
Error message
not found - make sure files are names *.old and *.new in multi-file mode
What it means
RuleMatchDiffFinder's multi-file mode expects input files in *.old/*.new pairs that differ only in a two-character language-code placeholder (XX). When, after locating a matching .old file, the corresponding .new file does not exist in the same directory, main() throws this RuntimeException naming the expected .new path.
Source
Thrown at languagetool-dev/src/main/java/org/languagetool/dev/diff/RuleMatchDiffFinder.java:665
if (args.length != 4) {
printUsageAndExit();
}
System.out.println("Running in multi-file mode, replacing 'XX' in filenames with lang codes...");
String file1 = args[0];
String file3 = args[2];
String date = args[3];
File dir = new File(file1).getParentFile();
String templateName = new File(file1).getName();
int varPos = templateName.indexOf("XX");
for (String file : dir.list()) {
if (file.length() >= varPos + 1) {
StringBuilder tempName = new StringBuilder(file).replace(varPos, varPos + 2, "XX");
if (tempName.toString().equals(templateName)) {
String langCode = file.substring(varPos, varPos + 2);
String tempNameNew = file.replace(".old", ".new");
File newFile = new File(dir, tempNameNew);
if (!newFile.exists()) {
throw new RuntimeException(tempNameNew + " not found - make sure files are names *.old and *.new in multi-file mode");
}
System.out.println("==== " + file + " =================================");
File oldFile = new File(dir, file);
String outputDir = file3.replace("XX", langCode);
diffFinder.run(parser, oldFile, newFile, new File(outputDir), langCode, date);
}
}
}
} else {
if (args.length != 5) {
System.out.println("Usage: " + RuleMatchDiffFinder.class.getSimpleName() + " <matches1> <matches2> <resultDir> <langCode> <date>");
System.out.println(" <matches1> and <matches2> are text outputs of different versions of org.languagetool.dev.dumpcheck.SentenceSourceChecker run on the same input");
System.out.println(" or JSON outputs from org.languagetool.dev.httpchecker.HttpApiSentenceChecker");
System.exit(1);
}
File file1 = new File(args[0]);
File file2 = new File(args[1]);
File outputDir = new File(args[2]);View on GitHub (pinned to 2e990059ce)
Solutions
- Create or restore the missing .new file at the exact path printed in the message
- Ensure both files use the exact *.old and *.new suffixes in the same directory and share the name template with XX placeholders
- Re-run after renaming, e.g. mv mismatched.new.ext proper-name.new
- If single-language, use the two-file mode (oldFile newFile resultDir langCode date) instead of multi-file mode
Example fix
// before mv results-de.old.txt results-de.new.txt # wrong name template // after mv results-XX.old.txt results-XX.new.txt # or exactly matching de.old/de.new pair
Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(args[0]);
for (File f : dir.listFiles((d, n) -> n.endsWith(".old"))) {
File newF = new File(dir, f.getName().replace(".old", ".new"));
if (!newF.isFile()) throw new IllegalStateException("missing pair: " + newF);
} Type guard
static boolean isCompleteOldNewPair(File oldFile) {
return oldFile.isFile() && new File(oldFile.getParentFile(),
oldFile.getName().replace(".old", ".new")).isFile();
} Try / catch
try {
diffFinderMain(args);
} catch (RuntimeException e) {
if (e.getMessage().contains("*.old and *.new")) {
System.err.println("fix file pair: " + e.getMessage());
} else throw e;
} Prevention
- Always create .old/.new files together in the same directory
- Use the exact XX language-code template in multi-file names
- Script the pair creation so one side cannot be forgotten
When it happens
Trigger: Running the diff finder in multi-file mode (directory of files whose names contain the 'XX' language placeholder) where a file 'foo.old' exists but 'foo.new' is missing, or the .new file was named differently (e.g. '.diff', wrong extension, different case).
Common situations: Forgot to copy/rename one side of a before/after diff pair; partial checkout or cleanup removed *.new files; files renamed so the '.old'/'.new' suffix convention broke.
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
- File not found: ${inputFile}
- Rules Configuration file cannot be found:
- Remote rules configuration file cannot be found:
- beolingusFile not found:
- ngramLangIdentData does not exist or is a directory (needs t
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/6ac72ce3f9b912ff.
Report an issue: GitHub.