{"record":{"id":"a47de9a3591af2a8","repo":"junit-team/junit5","slug":"failed-to-retrieve-canonical-path-for-directory-a47de9","errorCode":null,"errorMessage":"Failed to retrieve canonical path for directory: ${directory}","messagePattern":"Failed to retrieve canonical path for directory: (.+?)","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/DirectorySource.java","lineNumber":55,"sourceCode":"\t/**\n\t * Create a new {@code DirectorySource} using the supplied\n\t * {@linkplain File directory}.\n\t *\n\t * @param directory the source directory; must not be {@code null}\n\t */\n\tpublic static DirectorySource from(File directory) {\n\t\treturn new DirectorySource(directory);\n\t}\n\n\tprivate final File directory;\n\n\tprivate DirectorySource(File directory) {\n\t\tPreconditions.notNull(directory, \"directory must not be null\");\n\t\ttry {\n\t\t\tthis.directory = directory.getCanonicalFile();\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new JUnitException(\"Failed to retrieve canonical path for directory: \" + directory, ex);\n\t\t}\n\t}\n\n\t/**\n\t * Get the {@link URI} for the source {@linkplain #getFile directory}.\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}\n\n\t/**\n\t * Get the source {@linkplain File directory}.\n\t *\n\t * @return the source directory; never {@code null}\n\t */","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/DirectorySource.java#L37-L73","documentation":"DirectorySource.from(File) constructs a DirectorySource by canonicalizing the File (getCanonicalFile()). If canonicalization throws IOException, a JUnitException wraps it. DirectorySource is a test source descriptor used by the engine to record where a container (e.g. a directory-based discovery) comes from.","triggerScenarios":"Creating a DirectorySource for a File whose canonical path cannot be resolved: a broken symlink in the chain, a parent directory not traversable, or an OS/filesystem resolution error. Unlike the DiscoverySelectors variant, this fires when the engine builds a source descriptor, not when the user selects.","commonSituations":"Engine/build tool canonicalizing a discovered directory that sits behind restricted parents or a symlink chain; an IDE-supplied path that resolves differently under the test JVM; network filesystem canonicalization failures.","solutions":["Ensure all parent directories are readable and traversable by the test JVM.","Resolve or remove symlinks before discovery (use a canonical absolute File).","Configure the build tool to pass canonical absolute paths to the engine.","If building the source programmatically, pass a File whose getCanonicalFile() is known to succeed (resolve it earlier and handle the IOException yourself)."],"exampleFix":"// before\nDirectorySource src = DirectorySource.from(new File(\"/links/tests\"));\n// after — pre-canonicalize and handle, or use a real path\nFile canonical = new File(\"/links/tests\").getCanonicalFile(); // resolve once where you control the error\nDirectorySource src = DirectorySource.from(canonical);","handlingStrategy":"validation","validationCode":"// Pre-canonicalize the directory before the engine does it.\nimport java.io.File;\nFile d = userDir;\nif (!d.isDirectory()) throw new IllegalArgumentException(\"Not a directory: \" + d);\nFile canonical;\ntry { canonical = d.getCanonicalFile(); } catch (IOException e) {\n  throw new IllegalArgumentException(\"Cannot canonicalize \" + d + \": \" + e.getMessage(), e);\n}\nDirectorySource src = DirectorySource.from(canonical);\n","typeGuard":null,"tryCatchPattern":"try { return DirectorySource.from(dir); } catch (org.junit.platform.commons.JUnitException e) { /* pre-canonicalize and retry, or report */ throw e; }","preventionTips":["Resolve the canonical File yourself where you can handle the IOException, then pass it to DirectorySource.from().","Ensure parent directories are traversable by the test JVM.","Avoid broken symlinks in the directory 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"}