google/guava · error · IllegalStateException
A compound CollectionSize doesn't specify a number of elemen
Error message
A compound CollectionSize doesn't specify a number of elements.
What it means
Thrown by CollectionSize.getNumElements() when called on a compound size. ZERO/ONE/SEVERAL each carry a concrete element count; the compound ANY (built from the other three) has numElements == null because it does not represent a single size. The generator iterates concrete sizes, so asking ANY for a count is a programmer error.
Source
Thrown at android/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java:84
this.implied = emptySet();
this.numElements = numElements;
}
CollectionSize(Feature<? super Collection>... implied) {
// Keep the order here, so that PerCollectionSizeTestSuiteBuilder
// gives a predictable order of test suites.
this.implied = copyToSet(implied);
this.numElements = null;
}
@Override
public Set<Feature<? super Collection>> getImpliedFeatures() {
return implied;
}
public int getNumElements() {
if (numElements == null) {
throw new IllegalStateException(
"A compound CollectionSize doesn't specify a number of elements.");
}
return numElements;
}
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@TesterAnnotation
public @interface Require {
CollectionSize[] value() default {};
CollectionSize[] absent() default {};
}
}
View on GitHub (pinned to 94f39958ba)
Solutions
- Expand compound sizes before calling getNumElements(): iterate the concrete values CollectionSize.ZERO/ONE/SEVERAL, or filter the set to non-compound members.
- Guard calls with a check (e.g. size != CollectionSize.ANY) before invoking getNumElements().
- Use the builder's size-splitting path (PerCollectionSizeTestSuiteBuilder) which already expands ANY rather than calling getNumElements() on it.
Example fix
// before
int n = CollectionSize.ANY.getNumElements();
// after
for (CollectionSize size : asList(CollectionSize.ZERO, CollectionSize.ONE, CollectionSize.SEVERAL)) {
int n = size.getNumElements();
// ...
} Defensive patterns
Strategy: validation
Validate before calling
for (CollectionSize s : sizes) {
if (s == CollectionSize.ANY) continue; // skip compound
int n = s.getNumElements();
} Type guard
static boolean isConcreteSize(CollectionSize s) { return s != CollectionSize.ANY && s.getNumElementsIfExists() != null; } Prevention
- Filter compound features out before calling getNumElements().
- Document which callers may receive compound CollectionSize values.
When it happens
Trigger: Calling CollectionSize.ANY.getNumElements(), or passing ANY into code (e.g. OneSizeGenerator) that calls getNumElements() directly instead of first expanding ANY into its implied concrete sizes.
Common situations: Writing a custom generator/tester that iterates over a feature set and calls getNumElements() without filtering out compound features; assuming ANY is a concrete size.
Related errors
- Call withFeatures() before createTestSuite().
- %s: no CollectionSizes specified (check the argument to Feat
- Call using() before createTestSuite().
- Call named() before createTestSuite().
- Error extracting features from tester annotation.
AI-assisted analysis of google/guava@94f39958ba (2026-08-13).
Data as JSON: /api/errors/d15044033cc53de9.
Report an issue: GitHub.