{"record":{"id":"d15044033cc53de9","repo":"google/guava","slug":"a-compound-collectionsize-doesn-t-specify-a-number","errorCode":null,"errorMessage":"A compound CollectionSize doesn't specify a number of elements.","messagePattern":"A compound CollectionSize doesn't specify a number of elements\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"android/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java","lineNumber":84,"sourceCode":"    this.implied = emptySet();\n    this.numElements = numElements;\n  }\n\n  CollectionSize(Feature<? super Collection>... implied) {\n    // Keep the order here, so that PerCollectionSizeTestSuiteBuilder\n    // gives a predictable order of test suites.\n    this.implied = copyToSet(implied);\n    this.numElements = null;\n  }\n\n  @Override\n  public Set<Feature<? super Collection>> getImpliedFeatures() {\n    return implied;\n  }\n\n  public int getNumElements() {\n    if (numElements == null) {\n      throw new IllegalStateException(\n          \"A compound CollectionSize doesn't specify a number of elements.\");\n    }\n    return numElements;\n  }\n\n  @Retention(RetentionPolicy.RUNTIME)\n  @Inherited\n  @TesterAnnotation\n  public @interface Require {\n    CollectionSize[] value() default {};\n\n    CollectionSize[] absent() default {};\n  }\n}\n","sourceCodeStart":66,"sourceCodeEnd":99,"githubUrl":"https://github.com/google/guava/blob/94f39958baf7ad51ddf9c70e406ed6b188194daa/android/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java#L66-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nint n = CollectionSize.ANY.getNumElements();\n\n// after\nfor (CollectionSize size : asList(CollectionSize.ZERO, CollectionSize.ONE, CollectionSize.SEVERAL)) {\n  int n = size.getNumElements();\n  // ...\n}","handlingStrategy":"validation","validationCode":"for (CollectionSize s : sizes) {\n  if (s == CollectionSize.ANY) continue; // skip compound\n  int n = s.getNumElements();\n}","typeGuard":"static boolean isConcreteSize(CollectionSize s) { return s != CollectionSize.ANY && s.getNumElementsIfExists() != null; }","tryCatchPattern":null,"preventionTips":["Filter compound features out before calling getNumElements().","Document which callers may receive compound CollectionSize values."],"tags":["guava-testlib","illegal-state","features","collection-size","api-misuse"],"backgroundTag":null,"analyzedSha":"94f39958baf7ad51ddf9c70e406ed6b188194daa","analyzedAt":"2026-08-13T22:50:30.265Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}