google/guava · error · ConflictingRequirementsException

Annotation requires to be %s features that earlier annotatio

Error message

Annotation requires to be %s features that earlier annotations required to be %s.

What it means

Thrown as ConflictingRequirementsException by FeatureUtil.checkConflict when requirements accumulated from earlier annotations (class-level, then method-level) conflict with a new annotation. Unlike error 7 (intra-annotation), this fires during cross-annotation merging in incorporateRequirements: a later annotation demands a feature be present while an earlier one demanded it absent (or vice-versa).

Source

Thrown at android/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java:289

    Set<Feature<?>> morePresentFeatures = moreRequirements.getPresentFeatures();
    Set<Feature<?>> moreAbsentFeatures = moreRequirements.getAbsentFeatures();
    checkConflict("absent", absentFeatures, "present", morePresentFeatures, source);
    checkConflict("present", presentFeatures, "absent", moreAbsentFeatures, source);
    presentFeatures.addAll(morePresentFeatures);
    absentFeatures.addAll(moreAbsentFeatures);
    return requirements;
  }

  // Used by incorporateRequirements() only
  private static void checkConflict(
      String earlierRequirement,
      Set<Feature<?>> earlierFeatures,
      String newRequirement,
      Set<Feature<?>> newFeatures,
      Object source)
      throws ConflictingRequirementsException {
    if (!disjoint(newFeatures, earlierFeatures)) {
      throw new ConflictingRequirementsException(
          String.format(
              Locale.ROOT,
              "Annotation requires to be %s features that earlier "
                  + "annotations required to be %s.",
              newRequirement,
              earlierRequirement),
          intersection(newFeatures, earlierFeatures),
          source);
    }
  }

  /**
   * Construct a new {@link java.util.Set} that is the intersection of the given sets.
   *
   * @deprecated Use {@link com.google.common.collect.Sets#intersection(Set, Set)} instead.
   */
  @Deprecated
  public static <T> Set<T> intersection(Set<? extends T> set1, Set<? extends T> set2) {

View on GitHub (pinned to 94f39958ba)

Solutions

  1. Read the formatted message (newRequirement vs earlierRequirement) and getConflicts() to identify the two annotations and the overlapping feature(s).
  2. Reconcile the class-level and method-level annotations so no feature is required present by one and absent by another.
  3. If you need a tester to opt out of a class-level feature, suppress that tester method instead of declaring it absent at method level while present at class level.

Example fix

// before
@CollectionFeature.Require(value = CollectionFeature.GENERAL_PURPOSE)
class MyListTester extends AbstractListTester {
  @CollectionFeature.Require(absent = CollectionFeature.SUPPORTS_REMOVE)
  public void testRemove() { ... } // GENERAL_PURPOSE implies SUPPORTS_REMOVE
}

// after
@CollectionFeature.Require(CollectionFeature.GENERAL_PURPOSE)
class MyListTester extends AbstractListTester {
  public void testRemove() { ... } // no conflicting method-level absence
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  // run suite / build requirements
} catch (ConflictingRequirementsException e) {
  // e.getConflicts() -> conflicting features; e.getSource() -> offending annotation
  throw new IllegalStateException("Feature conflict in testers: " + e.getConflicts()
      + " from " + e.getSource(), e);
}

Prevention

When it happens

Trigger: A class-level @CollectionFeature.Require that lists a feature in value(), combined with a method-level annotation (or another class annotation) that lists the same/overlapping feature in absent(); the merge in incorporateRequirements detects the overlap.

Common situations: Class-level @Feature.Require declaring broad support and a specific tester method overriding with absent for an overlapping feature; stacking multiple @Require-style annotations whose sets overlap after implication; refactoring a tester and forgetting a class-level annotation.

Related errors


AI-assisted analysis of google/guava@94f39958ba (2026-08-13). Data as JSON: /api/errors/9bc4984f35ff6f84. Report an issue: GitHub.