google/guava · error · IllegalStateException
Call withFeatures() before createTestSuite().
Error message
Call withFeatures() before createTestSuite().
What it means
Thrown by checkCanCreate() when createTestSuite() is invoked without withFeatures(...). The feature set drives which testers are selected/filtered, so an empty feature set would produce an empty, meaningless suite; the builder rejects it up front.
Source
Thrown at android/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java:215
TestSuite testerSuite =
makeSuiteForTesterClass((Class<? extends AbstractTester<?>>) testerClass);
if (testerSuite.countTestCases() > 0) {
suite.addTest(testerSuite);
}
}
return suite;
}
/** Throw {@link IllegalStateException} if {@link #createTestSuite()} can't be called yet. */
protected void checkCanCreate() {
if (subjectGenerator == null) {
throw new IllegalStateException("Call using() before createTestSuite().");
}
if (name == null) {
throw new IllegalStateException("Call named() before createTestSuite().");
}
if (features == null) {
throw new IllegalStateException("Call withFeatures() before createTestSuite().");
}
}
@SuppressWarnings("rawtypes") // class literals
protected abstract List<Class<? extends AbstractTester>> getTesters();
private boolean matches(Test test) {
Method method;
try {
method = extractMethod(test);
} catch (IllegalArgumentException e) {
logger.finer(Platform.format("%s: including by default: %s", test, e.getMessage()));
return true;
}
if (suppressedTests.contains(method)) {
logger.finer(Platform.format("%s: excluding because it was explicitly suppressed.", test));
return false;
}View on GitHub (pinned to 94f39958ba)
Solutions
- Add .withFeatures(...) with the concrete features the implementation supports (e.g. CollectionFeature.GENERAL_PURPOSE, CollectionSize.ANY) before createTestSuite().
- Confirm the feature list is non-empty and that the constants are imported from the correct feature enum (CollectionFeature, MapFeature, ListFeature, SetFeature).
- Keep the canonical chain order using(...) -> named(...) -> withFeatures(...) -> createTestSuite().
Example fix
// before
TestSuite suite = ListTestSuiteBuilder.using(gen)
.named("MyList")
.createTestSuite();
// after
TestSuite suite = ListTestSuiteBuilder.using(gen)
.named("MyList")
.withFeatures(ListFeature.GENERAL_PURPOSE, CollectionSize.ANY)
.createTestSuite(); Defensive patterns
Strategy: validation
Validate before calling
Feature<?>[] feats = { CollectionFeature.GENERAL_PURPOSE, CollectionSize.ANY };
if (feats.length == 0) throw new IllegalArgumentException("withFeatures() needs >=1 feature");
TestSuite suite = ListTestSuiteBuilder.using(gen).named("MyList").withFeatures(feats).createTestSuite(); Prevention
- Always include a CollectionSize in withFeatures for collection builders.
- Review the feature list during code review to ensure it is non-empty and correctly typed.
When it happens
Trigger: A builder chain missing the .withFeatures(...) step, or passing an empty varargs/iterable. features == null at line 214 (withFeatures sets it to a non-null set) trips the guard.
Common situations: Porting a suite and forgetting to copy the feature list; passing withFeatures() with no arguments; deleting features while debugging and forgetting to restore them.
Related errors
- Call using() before createTestSuite().
- Call named() before createTestSuite().
- %s: no CollectionSizes specified (check the argument to Feat
- A compound CollectionSize doesn't specify a number of elemen
- Error extracting features from tester annotation.
AI-assisted analysis of google/guava@94f39958ba (2026-08-13).
Data as JSON: /api/errors/8de404746ca88003.
Report an issue: GitHub.