{"record":{"id":"28e9146d51a544f8","repo":"languagetool-org/languagetool","slug":"resultdir-already-exists-but-is-a-file","errorCode":null,"errorMessage":"<resultDir> already exists, but is a file: ","messagePattern":"<resultDir> already exists, but is a file: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"languagetool-dev/src/main/java/org/languagetool/dev/diff/RuleMatchDiffFinder.java","lineNumber":687,"sourceCode":"            String outputDir = file3.replace(\"XX\", langCode);\n            diffFinder.run(parser, oldFile, newFile, new File(outputDir), langCode, date);\n          }\n        }\n      }\n    } else {\n      if (args.length != 5) {\n        System.out.println(\"Usage: \" + RuleMatchDiffFinder.class.getSimpleName() + \" <matches1> <matches2> <resultDir> <langCode> <date>\");\n        System.out.println(\" <matches1> and <matches2> are text outputs of different versions of org.languagetool.dev.dumpcheck.SentenceSourceChecker run on the same input\");\n        System.out.println(\"                           or JSON outputs from org.languagetool.dev.httpchecker.HttpApiSentenceChecker\");\n        System.exit(1);\n      }\n      File file1 = new File(args[0]);\n      File file2 = new File(args[1]);\n      File outputDir = new File(args[2]);\n      String langCode = args[3];\n      String date = args[4];\n      if (outputDir.exists() && outputDir.isFile()) {\n        throw new IOException(\"<resultDir> already exists, but is a file: \" + outputDir);\n      }\n      if (!outputDir.exists()) {\n        boolean mkdir = outputDir.mkdir();\n        if (!mkdir) {\n          throw new IOException(\"Could not create directory \" + outputDir);\n        }\n      }\n      diffFinder.run(parser, file1, file2, outputDir, langCode, date);\n    }\n  }\n\n}\n","sourceCodeStart":669,"sourceCodeEnd":700,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-dev/src/main/java/org/languagetool/dev/diff/RuleMatchDiffFinder.java#L669-L700","documentation":"In RuleMatchDiffFinder's two-file mode, the third argument <resultDir> is the output directory. If that path already exists but is a regular file rather than a directory, main() throws this IOException because results cannot be written into it.","triggerScenarios":"Passing an existing file path (e.g. results.txt) as args[2] instead of a directory name; typo where the output arg accidentally points at an input file.","commonSituations":"Script variable reused from a previous run that holds a file path; shell glob expanding to a file; copying an example command but leaving a filename as the output argument.","solutions":["Remove the file at that path or choose a new directory name for <resultDir>","mkdir the directory beforehand if you want to reuse the name","Check your CLI arguments: args are oldFile newFile resultDir langCode date"],"exampleFix":"// before\njava RuleMatchDiffFinder old.txt new.txt results.txt de 2024-01-01\n// after\nmkdir -p results\njava RuleMatchDiffFinder old.txt new.txt results de 2024-01-01","handlingStrategy":"validation","validationCode":"File out = new File(args[2]);\nif (out.exists() && out.isFile()) {\n  throw new IllegalArgumentException(\"resultDir must be a directory: \" + out);\n}\nif (!out.exists()) out.mkdirs();","typeGuard":"static boolean isValidResultDir(String path) {\n  File f = new File(path);\n  return !f.exists() || f.isDirectory();\n}","tryCatchPattern":"try {\n  diffFinderMain(args);\n} catch (IOException e) {\n  if (e.getMessage().startsWith(\"<resultDir> already exists\")) {\n    System.err.println(\"pass a directory, not a file: \" + args[2]);\n  } else throw e;\n}","preventionTips":["Never reuse a file-path variable as the output directory argument","mkdir the output directory before invoking the tool","Validate argv ordering: oldFile newFile resultDir langCode date"],"tags":["java","io-exception","cli-arguments"],"backgroundTag":"invalid-cli-argument","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}