junit-team/junit5 · error · JUnitException

Failed to retrieve canonical path for directory

Error message

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

What it means

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.

Solutions

  1. Ensure all parent directories are readable and traversable by the test JVM.
  2. Resolve or remove symlinks before discovery (use a canonical absolute File).
  3. Configure the build tool to pass canonical absolute paths to the engine.
  4. If building the source programmatically, pass a File whose getCanonicalFile() is known to succeed (resolve it earlier and handle the IOException yourself).

Example fix

// before
DirectorySource src = DirectorySource.from(new File("/links/tests"));
// after — pre-canonicalize and handle, or use a real path
File canonical = new File("/links/tests").getCanonicalFile(); // resolve once where you control the error
DirectorySource src = DirectorySource.from(canonical);
Defensive patterns

Strategy: validation

Validate before calling

// Pre-canonicalize the directory before the engine does it.
import java.io.File;
File d = userDir;
if (!d.isDirectory()) throw new IllegalArgumentException("Not a directory: " + d);
File canonical;
try { canonical = d.getCanonicalFile(); } catch (IOException e) {
  throw new IllegalArgumentException("Cannot canonicalize " + d + ": " + e.getMessage(), e);
}
DirectorySource src = DirectorySource.from(canonical);

Try / catch

try { return DirectorySource.from(dir); } catch (org.junit.platform.commons.JUnitException e) { /* pre-canonicalize and retry, or report */ throw e; }

Prevention

When it happens

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

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

Related errors


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

Appendix: source

Thrown at junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/DirectorySource.java:55

	/**
	 * Create a new {@code DirectorySource} using the supplied
	 * {@linkplain File directory}.
	 *
	 * @param directory the source directory; must not be {@code null}
	 */
	public static DirectorySource from(File directory) {
		return new DirectorySource(directory);
	}

	private final File directory;

	private DirectorySource(File directory) {
		Preconditions.notNull(directory, "directory must not be null");
		try {
			this.directory = directory.getCanonicalFile();
		}
		catch (IOException ex) {
			throw new JUnitException("Failed to retrieve canonical path for directory: " + directory, ex);
		}
	}

	/**
	 * Get the {@link URI} for the source {@linkplain #getFile directory}.
	 *
	 * @return the source {@code URI}; never {@code null}
	 */
	@Override
	public URI getUri() {
		return getFile().toURI();
	}

	/**
	 * Get the source {@linkplain File directory}.
	 *
	 * @return the source directory; never {@code null}
	 */

View on GitHub (pinned to f070c699a0)