{"record":{"id":"77648448487073c5","repo":"HMCL-dev/HMCL","slug":"source-srcfile-does-not-exist","errorCode":null,"errorMessage":"Source '<srcFile>' does not exist","messagePattern":"Source '<srcFile>' does not exist","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java","lineNumber":476,"sourceCode":"public static void copyFile(Path srcFile, Path destFile)\n        throws IOException {\n    Objects.requireNonNull(srcFile, \"Source must not be null\");\n    Objects.requireNonNull(destFile, \"Destination must not be null\");\n    if (!Files.exists(srcFile))\n        throw new FileNotFoundException(\"Source '\" + srcFile + \"' does not exist\");\n    if (Files.isDirectory(srcFile))\n        throw new IOException(\"Source '\" + srcFile + \"' exists but is a directory\");\n    Files.createDirectories(destFile.getParent());\n    if (Files.exists(destFile) && !Files.isWritable(destFile))\n        throw new IOException(\"Destination '\" + destFile + \"' exists but is read-only\");\n\n    Files.copy(srcFile, destFile, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);\n}","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java#L458-L494","documentation":"Guard in FileUtils.copyFile: the source path does not exist, so the copy cannot start. A FileNotFoundException naming the missing source is thrown before any I/O is attempted; generic pre-condition validation of the srcFile argument.","triggerScenarios":"Calling FileUtils.copyFile(srcFile, destFile) with a srcFile that was deleted, never created, or whose path is misspelled/relatively resolved.","commonSituations":"Copying mod profiles or game assets after a prior cleanup step removed them; wrong working directory making relative paths resolve elsewhere; race with another process deleting the file.","solutions":["Verify the source path exists (Files.exists) and is spelled/resolved correctly before calling copyFile","Use absolute paths or resolve against the correct base directory","Recreate or re-download the missing source before copying","Skip or log-and-continue when the source is legitimately absent"],"exampleFix":"// before\nFileUtils.copyFile(new File(\"config.json\").toPath(), backup);\n// after\nPath src = gameDir.resolve(\"config.json\");\nif (Files.exists(src)) FileUtils.copyFile(src, backup);","handlingStrategy":"validation","validationCode":"Path src = baseDir.resolve(\"file.dat\").toAbsolutePath().normalize();\nif (!Files.isRegularFile(src)) throw new FileNotFoundException(src.toString());","typeGuard":"static boolean isRegularFileOrNull(Path p) { return p != null && Files.isRegularFile(p); }","tryCatchPattern":"try {\n    FileUtils.copyFile(src, dest);\n} catch (FileNotFoundException e) {\n    // re-download/recreate the missing source\n}","preventionTips":["Always resolve relative paths against an explicit base directory","Check Files.exists/isRegularFile before copying","Re-download sources that prior steps may have deleted","Log the absolute path when configuring copy operations"],"tags":["io","file","copy"],"backgroundTag":"file-not-found","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}