chinabugotech/hutool · error · IllegalArgumentException
attribute [{}] cannot mirror for [{}], because it's already
Error message
attribute [{}] cannot mirror for [{}], because it's already mirrored for [{}] What it means
One of two near-identical messages from MirrorLinkAnnotationPostProcessor.checkMirrorRelation. This variant fires when an attribute is annotated @Link(type=MIRROR_FOR) pointing at another attribute, but that mirror relationship is inconsistent: specifically the branch where only one side has already been mirrored to a different target. It indicates a malformed mutual @Link/@MirrorFor setup that the processor cannot reconcile.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java:111
}
// 镜像字段已经跟其他字段形成镜像
else if (!originalAttributeMirrored && mirrorAttributeMirrored) {
errorMsg = CharSequenceUtil.format(
"attribute [{}] cannot mirror for [{}], because it's already mirrored for [{}]",
mirror.getAttribute(), original.getAttribute(), ((MirroredAnnotationAttribute)mirror).getLinked()
);
}
// 两者都形成了镜像,但是都未指向对方,理论上不会存在该情况
else {
errorMsg = CharSequenceUtil.format(
"attribute [{}] cannot mirror for [{}], because [{}] already mirrored for [{}] and [{}] already mirrored for [{}]",
mirror.getAttribute(), original.getAttribute(),
mirror.getAttribute(), ((MirroredAnnotationAttribute)mirror).getLinked(),
original.getAttribute(), ((MirroredAnnotationAttribute)original).getLinked()
);
}
throw new IllegalArgumentException(errorMsg);
}
/**
* 基本校验
*/
private void checkMirrorRelation(Link annotation, AnnotationAttribute original, AnnotationAttribute mirror) {
// 镜像属性必须存在
checkLinkedAttributeNotNull(original, mirror, annotation);
// 镜像属性返回值必须一致
checkAttributeType(original, mirror);
// 镜像属性上必须存在对应的注解
final Link mirrorAttributeAnnotation = getLinkAnnotation(mirror, RelationType.MIRROR_FOR);
Assert.isTrue(
ObjectUtil.isNotNull(mirrorAttributeAnnotation) && RelationType.MIRROR_FOR.equals(mirrorAttributeAnnotation.type()),
"mirror attribute [{}] of original attribute [{}] must marked by @Link, and also @LinkType.type() must is [{}]",
mirror.getAttribute(), original.getAttribute(), RelationType.MIRROR_FOR
);
checkLinkedSelf(original, mirror);View on GitHub (pinned to 8870454b2a)
Solutions
- Ensure MIRROR_FOR links are symmetric: if A mirrors B, B must mirror A.
- Remove stray @Link annotations left from refactoring.
- Inspect the error's listed attributes to find which side is double-linked and fix its @Link target.
Defensive patterns
Strategy: validation
Validate before calling
// verify mirror pairs are symmetric before relying on synthesis
boolean aMirrorsB = isMirrorFor(A.class, "a", B.class, "b");
boolean bMirrorsA = isMirrorFor(B.class, "b", A.class, "a");
if (aMirrorsB != bMirrorsA) throw new IllegalStateException("asymmetric mirror"); Prevention
- Always declare @Link MIRROR_FOR on both members of a pair.
- Avoid mixing @Alias and @Link MIRROR_FOR on the same member.
When it happens
Trigger: Defining @Link(... MIRROR_FOR) on attribute A pointing to B, while B's @Link points elsewhere (or B has no reciprocal @Link), creating an asymmetric mirror graph. Mixing @Alias with @Link MIRROR_FOR on overlapping members.
Common situations: Building a custom composed-annotation hierarchy where mirrored members are not declared pairwise; refactoring one half of a mirror pair and forgetting the other; version upgrade that changed mirror semantics.
Related errors
- attribute [{}] cannot mirror for [{}], because [{}] already
- No method for alias: [{}]
- Failed to create AIConfig instance
- No constructor provided
- No constructor provided
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/dc26cf0b9eaebe0e.
Report an issue: GitHub.