google/guava · error · ParameterHasNoDistinctValueException

Cannot generate distinct value for parameter %s of %s

Error message

Cannot generate distinct value for parameter %s of %s

What it means

Thrown as ParameterHasNoDistinctValueException during ClassSanityTester's equals test when it cannot produce a second, distinct non-null value for a constructor/factory parameter. To verify equals, the tester needs at least two distinguishable argument values per parameter; if the only candidate equals the first (and it is not a single-value enum), the equals test cannot be constructed.

Source

Thrown at android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java:613

    EqualsTester tester =
        new EqualsTester(
            /* itemReporter= */ item -> {
              List<Object> factoryArgs = argGroups.get(item.groupNumber).get(item.itemNumber);
              return factory.getName()
                  + "("
                  + Joiner.on(", ").useForNull("null").join(factoryArgs)
                  + ")";
            });
    tester.addEqualityGroup(instance, createInstance(factory, equalArgs));
    for (int i = 0; i < params.size(); i++) {
      List<Object> newArgs = new ArrayList<>(args);
      Object newArg = argGenerators.get(i).generateFresh(params.get(i).getType());

      if (newArg == null || Objects.equals(args.get(i), newArg)) {
        if (params.get(i).getType().getRawType().isEnum()) {
          continue; // Nothing better we can do if it's single-value enum
        }
        throw new ParameterHasNoDistinctValueException(params.get(i));
      }
      newArgs.set(i, newArg);
      tester.addEqualityGroup(createInstance(factory, newArgs));
      argGroups.add(ImmutableList.of(newArgs));
    }
    tester.testEquals();
  }

  /**
   * Returns dummy factory arguments that are equal to {@code args} but may be different instances,
   * to be used to construct a second instance of the same equality group.
   */
  @SuppressWarnings("ReferenceEquality") // checking for the case of equal but non-identical objects
  private List<Object> generateEqualFactoryArguments(
      Invokable<?, ?> factory, List<Parameter> params, List<Object> args)
      throws ParameterNotInstantiableException,
          FactoryMethodReturnsNullException,
          InvocationTargetException,

View on GitHub (pinned to 94f39958ba)

Solutions

  1. Register sample/fresh distinct instances for the parameter type via ClassSanityTester.setDefault(Class, instance...) / setDistinctValues(Class, a, b).
  2. Provide a FreshValueGenerator sample for the type so the tester can mint a distinct value.
  3. If the parameter is genuinely single-valued or not relevant to equality, annotate it or exclude the class/field from the equals test.

Example fix

// before
sanityTester.testEquals(MyWrapper.class); // ctor takes Clock -> no distinct value

// after
sanityTester.setDistinctValues(Clock.class,
    Clock.systemUTC(), Clock.system("UTC"));
sanityTester.testEquals(MyWrapper.class);
Defensive patterns

Strategy: validation

Validate before calling

sanityTester.setDistinctValues(MyInterface.class, instanceA, instanceB);
sanityTester.testEquals(MyType.class);

Try / catch

try { sanityTester.testEquals(MyType.class); }
catch (ClassSanityTester.ParameterHasNoDistinctValueException e) {
  // read e.getMessage() to find the parameter, register a distinct value, retry
}

Prevention

When it happens

Trigger: Calling testEquals()/testAll() on a class whose constructor parameter has a type for which FreshValueGenerator cannot synthesize a fresh distinct value (e.g. an opaque interface/type with no registered sample instances and no concrete default).

Common situations: A value class whose constructor takes an interface type with no registered defaults; third-party types not covered by setDefault; a parameter whose only sample value collides with the first.

Related errors


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