junit-team/junit5 · error · JUnitException
'ResourceLockTarget.CHILDREN' is not supported for methods.
Error message
'ResourceLockTarget.CHILDREN' is not supported for methods. Invalid method: <method>
What it means
Thrown by MethodBasedTestDescriptor.getExclusiveResourceCollector() when a test method is annotated with @ResourceLock whose target is ResourceLockTarget.CHILDREN. CHILDREN only makes sense on a container (class-level) descriptor because a method has no child tests, so the engine rejects it as a JUnitException.
Source
Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/MethodBasedTestDescriptor.java:133
Validatable.reportAndClear(this.methodInfo.discoveryIssues, reporter);
DisplayNameUtils.validateAnnotation(getTestMethod(), //
() -> "method '%s'".formatted(getTestMethod().toGenericString()), //
// Use _declaring_ class here because that's where the `@DisplayName` annotation is declared
() -> MethodSource.from(getTestMethod()), //
reporter);
}
// --- Node ----------------------------------------------------------------
@Override
public ExclusiveResourceCollector getExclusiveResourceCollector() {
// There's no need to cache this as this method should only be called once
ExclusiveResourceCollector collector = ExclusiveResourceCollector.from(getTestMethod());
if (collector.getStaticResourcesFor(CHILDREN).findAny().isPresent()) {
String message = "'ResourceLockTarget.CHILDREN' is not supported for methods." + //
" Invalid method: " + getTestMethod();
throw new JUnitException(message);
}
return collector;
}
@Override
public Function<ResourceLocksProvider, Set<ResourceLocksProvider.Lock>> getResourceLocksProviderEvaluator() {
return enclosingInstanceTypesDependentResourceLocksProviderEvaluator(this::getEnclosingTestClasses,
(provider, enclosingInstanceTypes) -> provider.provideForMethod(enclosingInstanceTypes, getTestClass(),
getTestMethod()));
}
@Override
protected Optional<ExecutionMode> getExplicitExecutionMode() {
return getExecutionModeFromAnnotation(getTestMethod());
}
/**View on GitHub (pinned to 956246301e)
Solutions
- Move the @ResourceLock(target = CHILDREN) annotation from the method to the enclosing test class.
- If the lock applies to the method itself, use the default target (or ResourceLockTarget.SELF).
- Search the codebase for @ResourceLock(.*CHILDREN on method-level annotations and remove target = CHILDREN there.
Example fix
// before
@Test
@org.junit.jupiter.api.parallel.ResourceLock(value = "db", target = ResourceLockTarget.CHILDREN)
void myTest() {}
// after
@org.junit.jupiter.api.parallel.ResourceLock(value = "db", target = ResourceLockTarget.CHILDREN)
class MyTest {
@Test void myTest() {}
} Defensive patterns
Strategy: validation
Validate before calling
// Scan test methods for the unsupported annotation shape
for (Method m : testClass.getDeclaredMethods()) {
ResourceLock rl = m.getAnnotation(ResourceLock.class);
if (rl != null && rl.target() == ResourceLockTarget.CHILDREN) {
throw new IllegalStateException("Method " + m + " uses CHILDREN target");
}
} Prevention
- Use ResourceLockTarget.CHILDREN only on class-level annotations.
- When copying a @ResourceLock from a class to a method, drop target = CHILDREN.
- Review parallel-execution annotations during code review for target misuse.
When it happens
Trigger: Annotating a @Test, @TestFactory, @RepeatedTest, @ParameterizedTest, or lifecycle method with @ResourceLock(value = "...", target = ResourceLockTarget.CHILDREN).
Common situations: Copy-pasting a class-level @ResourceLock(target = CHILDREN) annotation onto a test method; refactoring a @ClassOrderContext/@ResourceLocks block from the class onto individual methods without changing the target.
Related errors
- Task was deferred but should have been executed synchronousl
- Assumption failed:
- Assumption failed
- This class must not be instantiated
- Implement generateDisplayNameForNestedClass(List<Class<?>>,
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/58a2ed201264e0d6.json.
Report an issue: GitHub.