{"record":{"id":"5a6db2e8e12d5614","repo":"junit-team/junit5","slug":"failed-to-retrieve-canonical-path-for-file-file-5a6db2","errorCode":null,"errorMessage":"Failed to retrieve canonical path for file: ${file}","messagePattern":"Failed to retrieve canonical path for file: (.+?)","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/FileSource.java","lineNumber":77,"sourceCode":"\tpublic static FileSource from(File file, @Nullable FilePosition filePosition) {\n\t\treturn new FileSource(file, filePosition);\n\t}\n\n\tprivate final File file;\n\n\tprivate final @Nullable FilePosition filePosition;\n\n\tprivate FileSource(File file) {\n\t\tthis(file, null);\n\t}\n\n\tprivate FileSource(File file, @Nullable FilePosition filePosition) {\n\t\tPreconditions.notNull(file, \"file must not be null\");\n\t\ttry {\n\t\t\tthis.file = file.getCanonicalFile();\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new JUnitException(\"Failed to retrieve canonical path for file: \" + file, ex);\n\t\t}\n\t\tthis.filePosition = filePosition;\n\t}\n\n\tprivate FileSource(FileSource fileSource, @Nullable FilePosition filePosition) {\n\t\tthis.file = fileSource.file;\n\t\tthis.filePosition = filePosition;\n\t}\n\n\t/**\n\t * Get the {@link URI} for the source {@linkplain #getFile file}.\n\t *\n\t * @return the source {@code URI}; never {@code null}\n\t */\n\t@Override\n\tpublic URI getUri() {\n\t\treturn getFile().toURI();\n\t}","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/FileSource.java#L59-L95","documentation":"FileSource(File, position) constructor canonicalizes the File via getCanonicalFile(); an IOException is wrapped as JUnitException. FileSource is the engine's test source descriptor for a class/resource file. Symmetric to DirectorySource (118) but for files; the constructor is private so this fires via FileSource.from(...) which delegates here.","triggerScenarios":"Building a FileSource for a File whose canonical path resolution fails: broken symlink chain, unreadable parent directory, or an OS/filesystem resolution error. Occurs when the engine constructs a source descriptor for a discovered file.","commonSituations":"Discovered source file behind a symlink loop or restricted directory; IDE/build passing a path that the test JVM resolves differently; network-mounted filesystem intermittent canonicalization failures.","solutions":["Ensure all parent directories are readable and traversable by the test JVM.","Pre-canonicalize the File where you can handle the IOException, then pass the resolved File to FileSource.from().","Resolve symlinks before discovery so the engine receives a clean canonical path.","Reconfigure the build tool to supply canonical absolute file paths."],"exampleFix":"// before\nFileSource src = FileSource.from(new File(\"/links/MyClass.java\"));\n// after\nFile canonical = new File(\"/links/MyClass.java\").getCanonicalFile();\nFileSource src = FileSource.from(canonical);","handlingStrategy":"validation","validationCode":"// Pre-canonicalize the file before the engine constructs the FileSource.\nimport java.io.File;\nFile f = userFile;\nif (!f.isFile()) throw new IllegalArgumentException(\"Not a file: \" + f);\nFile canonical;\ntry { canonical = f.getCanonicalFile(); } catch (IOException e) {\n  throw new IllegalArgumentException(\"Cannot canonicalize \" + f + \": \" + e.getMessage(), e);\n}\nFileSource src = FileSource.from(canonical);\n","typeGuard":null,"tryCatchPattern":"try { return FileSource.from(file); } catch (org.junit.platform.commons.JUnitException e) { /* pre-canonicalize and retry, or report */ throw e; }","preventionTips":["Resolve the canonical File yourself first and pass it to FileSource.from().","Ensure parent directories are traversable by the test JVM.","Avoid broken symlinks in the file path chain."],"tags":["engine","filesystem","test-source","canonical-path"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}