{"record":{"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":"validation","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/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/DiscoverySelectors.java#L211-L247","documentation":"DiscoverySelectors.selectDirectory(File) validates non-null and isDirectory(), then calls directory.getCanonicalPath(). If canonical-path resolution throws IOException, a PreconditionViolationException wraps it. Symmetric to the file variant (116).","triggerScenarios":"Calling selectDirectory(dir) where File.getCanonicalPath() fails: unreadable parent directory in the chain, broken symlink, or an OS/filesystem error resolving the absolute path. Existence as a directory is already checked.","commonSituations":"Restricted directories where the JVM can stat the directory but not traverse a parent for canonicalization; symlink loops; container/namespace filesystem oddities; CI with bind mounts that confuse canonical resolution.","solutions":["Ensure read+execute permission on all parent directories so canonicalization can traverse them.","Fix or remove broken symlinks in the path.","Prefer selectDirectory(String) with a known absolute canonical path to avoid the getCanonicalPath() call.","Move the target to a location with straightforward path resolution."],"exampleFix":"// before\nDirectorySelector s = selectDirectory(new File(\"/opt/app/../../etc/tests\")); // complex/blocked parents\n// after\nDirectorySelector s = selectDirectory(\"/etc/tests\"); // absolute canonical path via the String overload","handlingStrategy":"validation","validationCode":"// Pre-validate that directory canonicalization will succeed.\nimport java.io.File;\nFile d = userDir;\nif (!d.isDirectory()) throw new IllegalArgumentException(\"Not an existing directory: \" + d);\ntry { d.getCanonicalPath(); } catch (IOException e) {\n  throw new IllegalArgumentException(\"Cannot canonicalize \" + d + \": \" + e.getMessage(), e);\n}\n// If at risk, prefer selectDirectory(absoluteCanonicalPathString).\n","typeGuard":null,"tryCatchPattern":"try { return selectDirectory(dir); } catch (PreconditionViolationException e) { return selectDirectory(dir.getAbsolutePath()); }","preventionTips":["Ensure the test JVM can read+traverse all parent directories of the target directory.","Prefer selectDirectory(String) with a known absolute canonical path when canonicalization is at risk.","Avoid broken symlinks in the path chain."],"tags":["discovery","directory-selector","filesystem","engine"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}