junit-team/junit5 · error · ExtensionConfigurationException

Can only resolve @TempDir %s of type java.nio.file.Path or j

Error message

Can only resolve @TempDir %s of type java.nio.file.Path or java.io.File but was: %s

What it means

Thrown as ExtensionConfigurationException by assertSupportedType when a @TempDir-annotated field or parameter has a type other than java.nio.file.Path or java.io.File. The TempDirectory extension only knows how to inject these two concrete types and refuses anything else at setup time.

Source

Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TempDirectory.java:210

	}

	private TempDirFactory determineTempDirFactory(TempDir tempDir) {
		Class<? extends TempDirFactory> factory = tempDir.factory();

		return factory == TempDirFactory.class //
				? this.configuration.getDefaultTempDirFactorySupplier().get()
				: ReflectionSupport.newInstance(factory);
	}

	private static void assertNonFinalField(Field field) {
		if (ModifierSupport.isFinal(field)) {
			throw new ExtensionConfigurationException("@TempDir field [" + field + "] must not be declared as final.");
		}
	}

	private static void assertSupportedType(String target, Class<?> type) {
		if (type != Path.class && type != File.class) {
			throw new ExtensionConfigurationException("Can only resolve @TempDir " + target + " of type "
					+ Path.class.getName() + " or " + File.class.getName() + " but was: " + type.getName());
		}
	}

	private Object getPathOrFile(Class<?> elementType, AnnotatedElementContext elementContext,
			ExtensionContext extensionContext, TempDir tempDir) {
		TempDirFactory factory = determineTempDirFactory(tempDir);
		Cleanup cleanup = new Cleanup(determineCleanupMode(tempDir), determineDeletionStrategy(tempDir));
		return getPathOrFile(elementType, elementContext, factory, cleanup, extensionContext);
	}

	private static Object getPathOrFile(Class<?> elementType, AnnotatedElementContext elementContext,
			TempDirFactory factory, Cleanup cleanup, ExtensionContext extensionContext) {

		Path path = extensionContext.getStore(NAMESPACE.append(elementContext)) //
				.computeIfAbsent(KEY,
					__ -> createTempDir(factory, cleanup, elementType, elementContext, extensionContext),
					CloseablePath.class) //

View on GitHub (pinned to f070c699a0)

Solutions

  1. Change the @TempDir field/parameter type to java.nio.file.Path (preferred) or java.io.File.
  2. If you need a richer abstraction, inject Path and build your wrapper object in @BeforeEach from it.

Example fix

// before
@TempDir
private String tmpPath; // wrong type

// after
@TempDir
private Path tmpPath;

@BeforeEach
void setup() { this.wrapper = new FolderWrapper(tmpPath); }
Defensive patterns

Strategy: type-guard

Validate before calling

for (Field f : MyTest.class.getDeclaredFields()) {
    if (f.isAnnotationPresent(TempDir.class)) {
        Class<?> t = f.getType();
        if (t != Path.class && t != File.class) {
            throw new IllegalStateException("@TempDir " + f + " must be Path or File, was " + t);
        }
    }
}

Type guard

boolean isTempDirType(Class<?> t) {
    return t == Path.class || t == File.class;
}

Prevention

When it happens

Trigger: Annotating a field/parameter typed as String, File[], Path[], InputStream, or any custom type with @TempDir. assertSupportedType(target, type) checks `type != Path.class && type != File.class` and throws.

Common situations: Confusing @TempDir with @TempDir factory APIs; migrating from JUnit 4 TemporaryFolder and typing the field as a Folder-like wrapper; declaring a generic Path subtype; Kotlin type alias that resolves to something else.

Related errors


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