{"id":"ed68793ffd9b7469","repo":"junit-team/junit5","slug":"failed-to-retrieve-canonical-path-for-directory","errorCode":null,"errorMessage":"Failed to retrieve canonical path for directory: ${directory}","messagePattern":"Failed to retrieve canonical path for directory: (.+?)","errorType":"exception","errorClass":"PreconditionViolationException","httpStatus":null,"severity":"error","filePath":"junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/DiscoverySelectors.java","lineNumber":229,"sourceCode":"\t * <p>This method selects the directory in its {@linkplain File#getCanonicalPath()\n\t * canonical} form and throws a {@link PreconditionViolationException} if the\n\t * directory does not exist.\n\t *\n\t * @param directory the directory to select; never {@code null}\n\t * @see DirectorySelector\n\t * @see #selectDirectory(String)\n\t * @see #selectFile(String)\n\t * @see #selectFile(File)\n\t */\n\tpublic static DirectorySelector selectDirectory(File directory) {\n\t\tPreconditions.notNull(directory, \"Directory must not be null\");\n\t\tPreconditions.condition(directory.isDirectory(),\n\t\t\t() -> \"The supplied java.io.File [%s] must represent an existing directory\".formatted(directory));\n\t\ttry {\n\t\t\treturn new DirectorySelector(directory.getCanonicalPath());\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new PreconditionViolationException(\"Failed to retrieve canonical path for directory: \" + directory,\n\t\t\t\tex);\n\t\t}\n\t}\n\n\t/**\n\t * Create a list of {@code ClasspathRootSelectors} for the supplied\n\t * <em>classpath roots</em> (directories or JAR files).\n\t *\n\t * <p>Since the supplied paths are converted to {@link URI URIs}, the\n\t * {@link java.nio.file.FileSystem} that created them must be the\n\t * {@linkplain java.nio.file.FileSystems#getDefault() default} or one that\n\t * has been created by an installed\n\t * {@link java.nio.file.spi.FileSystemProvider}.\n\t *\n\t * <p>Since {@linkplain org.junit.platform.engine.TestEngine engines} are not\n\t * expected to modify the classpath, the classpath roots represented by the\n\t * resulting selectors must be on the classpath of the\n\t * {@linkplain Thread#getContextClassLoader() context class loader} of the","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/DiscoverySelectors.java#L211-L247","documentation":"Thrown by DiscoverySelectors.selectDirectory(File) at line 221-232 when directory.getCanonicalPath() raises IOException. The isDirectory() precondition (line 223) passes first, so this fires only when an existing directory's canonical path cannot be computed.","triggerScenarios":"Calling selectDirectory(dir) where 'dir' is a real directory but canonical resolution fails (broken parent symlink, I/O error on the filesystem, network filesystem dropped mid-operation, or OS-level path-length limits).","commonSituations":"Directories reached via dangling symlinks in the parent chain; selecting directories on transient mounts (Docker volumes, removable media); running under restricted security managers; CI runners with unusual filesystem layouts.","solutions":["Pre-resolve the canonical path with Path.toRealPath() and pass the resulting absolute path string to selectDirectory(String) which does not re-resolve.","Verify Files.isReadable(dir) and that the parent chain is intact before selection.","Replace directory symlinks with their real targets in test configuration.","Inspect the caused-by IOException for the precise filesystem error."],"exampleFix":"// before\nvar selector = DiscoverySelectors.selectDirectory(new File(dirPath));\n\n// after\nString canonical = Path.of(dirPath).toRealPath().toString();\nvar selector = DiscoverySelectors.selectDirectory(canonical); // String overload stores as-is","handlingStrategy":"validation","validationCode":"File d = new File(dirPath);\nif (!d.isDirectory()) throw new IllegalArgumentException(\"not a directory: \" + d);\nString canonical = Path.of(dirPath).toRealPath().toString();\nvar selector = DiscoverySelectors.selectDirectory(canonical);","typeGuard":null,"tryCatchPattern":"try {\n    return DiscoverySelectors.selectDirectory(dir);\n} catch (PreconditionViolationException e) {\n    throw new IllegalStateException(\"cannot canonicalize dir: \" + dir, e.getCause());\n}","preventionTips":["Pre-resolve directories with Path.toRealPath() and pass the String to selectDirectory(String).","Verify Files.isReadable(dir) before selection.","Replace directory symlinks with real targets in test configuration."],"tags":["junit-platform","discovery","io","filesystem","directory-selector","canonical-path"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}