projectlombok/lombok · error · DelegateRecursion

@Delegate does not support recursion (delegating to a type…

Error message

@Delegate does not support recursion (delegating to a type that itself has @Delegate members). Member "%s" is @Delegate in type "%s"

What it means

HandleDelegate throws DelegateRecursion (an error that lombok reports to the user) when a type delegated to via @Delegate itself contains members annotated with @Delegate. Lombok resolves delegation recursively, so nested @Delegate would loop infinitely; it cuts this off explicitly.

Solutions

  1. Remove @Delegate from the target type (B) and instead list its methods via @Delegate(types=...) on A, or delegate directly to the innermost type
  2. Break the cycle by re-structuring: delegate only to leaf types that have no @Delegate members
  3. Expose the needed methods manually on the delegating class instead of relying on chained delegation

Example fix

// before
class A { @Delegate B b; }
class B { @Delegate C c; }
// after
class A { @Delegate(types = {C.class}) B b; }
class B { @Delegate C c; }
Defensive patterns

Strategy: validation

Validate before calling

boolean hasNestedDelegate(Class<?> t) {
    try {
        for (Field f : t.getDeclaredFields())
            if (f.isAnnotationPresent(lombok.Delegate.class) || f.isAnnotationPresent(lombok.experimental.Delegate.class)) return true;
    } catch (Throwable ignored) {}
    return false;
}
// assert !hasNestedDelegate(TargetType.class) before annotating with @Delegate

Prevention

When it happens

Trigger: Annotating a field/method with @Delegate whose type (or any type in its hierarchy, including via interfaces) also has fields or methods annotated with @Delegate — detected in addMethodBindings when scanning the target type's members for a lombok.Delegate / lombok.experimental.Delegate annotation.

Common situations: Composing delegation across multiple classes, e.g. class A delegates to B while B delegates to C; often arises after a refactor added @Delegate deeper in the graph, or with generated code (IDE-added @Delegate) that the developer did not notice.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of projectlombok/lombok@6d6a3e9fec (2026-09-07). Data as JSON: /api/errors/3d0a8e15427e910f. Report an issue: GitHub.

Appendix: source

Thrown at src/core/lombok/javac/handlers/HandleDelegate.java:377

		public DelegateRecursion(String type, String member) {
			this.type = type;
			this.member = member;
		}
	}
	
	public void addMethodBindings(List<MethodSig> signatures, ClassType ct, JavacTypes types, Set<String> banList) throws DelegateRecursion {
		TypeSymbol tsym = ct.asElement();
		if (tsym == null) return;
		
		for (Symbol member : tsym.getEnclosedElements()) {
			for (Compound am : member.getAnnotationMirrors()) {
				String name = null;
				try {
					name = am.type.tsym.flatName().toString();
				} catch (Exception ignore) {}
				
				if ("lombok.Delegate".equals(name) || "lombok.experimental.Delegate".equals(name)) {
					throw new DelegateRecursion(ct.tsym.name.toString(), member.name.toString());
				}
			}
			if (member.getKind() != ElementKind.METHOD) continue;
			if (member.isStatic()) continue;
			if (member.isConstructor()) continue;
			ExecutableElement exElem = (ExecutableElement)member;
			if (!exElem.getModifiers().contains(Modifier.PUBLIC)) continue;
			ExecutableType methodType = (ExecutableType) types.asMemberOf(ct, member);
			String sig = printSig(methodType, member.name, types);
			if (!banList.add(sig)) continue; //If add returns false, it was already in there
			boolean isDeprecated = (member.flags() & DEPRECATED) != 0;
			signatures.add(new MethodSig(member.name, methodType, isDeprecated, exElem));
		}

		for (Type type : types.directSupertypes(ct)) {
			if (type instanceof ClassType) {
				addMethodBindings(signatures, (ClassType) type, types, banList);
			}

View on GitHub (pinned to 6d6a3e9fec)