junit-team/junit5 · error · PreconditionViolationException

Failed to retrieve canonical path for directory

Error message

Failed to retrieve canonical path for directory: ${directory}

What it means

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).

Solutions

  1. Ensure read+execute permission on all parent directories so canonicalization can traverse them.
  2. Fix or remove broken symlinks in the path.
  3. Prefer selectDirectory(String) with a known absolute canonical path to avoid the getCanonicalPath() call.
  4. Move the target to a location with straightforward path resolution.

Example fix

// before
DirectorySelector s = selectDirectory(new File("/opt/app/../../etc/tests")); // complex/blocked parents
// after
DirectorySelector s = selectDirectory("/etc/tests"); // absolute canonical path via the String overload
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate that directory canonicalization will succeed.
import java.io.File;
File d = userDir;
if (!d.isDirectory()) throw new IllegalArgumentException("Not an existing directory: " + d);
try { d.getCanonicalPath(); } catch (IOException e) {
  throw new IllegalArgumentException("Cannot canonicalize " + d + ": " + e.getMessage(), e);
}
// If at risk, prefer selectDirectory(absoluteCanonicalPathString).

Try / catch

try { return selectDirectory(dir); } catch (PreconditionViolationException e) { return selectDirectory(dir.getAbsolutePath()); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/ed68793ffd9b7469. Report an issue: GitHub.

Appendix: source

Thrown at junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/DiscoverySelectors.java:229

	 * <p>This method selects the directory in its {@linkplain File#getCanonicalPath()
	 * canonical} form and throws a {@link PreconditionViolationException} if the
	 * directory does not exist.
	 *
	 * @param directory the directory to select; never {@code null}
	 * @see DirectorySelector
	 * @see #selectDirectory(String)
	 * @see #selectFile(String)
	 * @see #selectFile(File)
	 */
	public static DirectorySelector selectDirectory(File directory) {
		Preconditions.notNull(directory, "Directory must not be null");
		Preconditions.condition(directory.isDirectory(),
			() -> "The supplied java.io.File [%s] must represent an existing directory".formatted(directory));
		try {
			return new DirectorySelector(directory.getCanonicalPath());
		}
		catch (IOException ex) {
			throw new PreconditionViolationException("Failed to retrieve canonical path for directory: " + directory,
				ex);
		}
	}

	/**
	 * Create a list of {@code ClasspathRootSelectors} for the supplied
	 * <em>classpath roots</em> (directories or JAR files).
	 *
	 * <p>Since the supplied paths are converted to {@link URI URIs}, the
	 * {@link java.nio.file.FileSystem} that created them must be the
	 * {@linkplain java.nio.file.FileSystems#getDefault() default} or one that
	 * has been created by an installed
	 * {@link java.nio.file.spi.FileSystemProvider}.
	 *
	 * <p>Since {@linkplain org.junit.platform.engine.TestEngine engines} are not
	 * expected to modify the classpath, the classpath roots represented by the
	 * resulting selectors must be on the classpath of the
	 * {@linkplain Thread#getContextClassLoader() context class loader} of the

View on GitHub (pinned to f070c699a0)