microg/GmsCore · error · IllegalStateException

Must set attenuationBucketThresholdDb

Error message

Must set attenuationBucketThresholdDb

What it means

DailySummariesConfig.Builder.build() requires attenuationBucketThresholdDb to be explicitly set before constructing the config. The library throws IllegalStateException because the Exposure Notification API cannot compute per-exposure summary weights without the attenuation bucket boundaries. This is a fail-fast builder validation to prevent passing an incomplete config to the API.

Source

Thrown at play-services-nearby/src/main/java/com/google/android/gms/nearby/exposurenotification/DailySummariesConfig.java:188

    /**
     * A builder for {@link DailySummariesConfig}.
     */
    public static class DailySummariesConfigBuilder {
        private Double[] reportTypeWeights = new Double[ReportType.VALUES];
        private Double[] infectiousnessWeights = new Double[Infectiousness.VALUES];
        private List<Integer> attenuationBucketThresholdDb;
        private List<Double> attenuationBucketWeights;
        private int daysSinceExposureThreshold;
        private double minimumWindowScore;

        public DailySummariesConfigBuilder() {
            Arrays.fill(reportTypeWeights, 0.0);
            Arrays.fill(infectiousnessWeights, 0.0);
        }

        public DailySummariesConfig build() {
            if (attenuationBucketThresholdDb == null)
                throw new IllegalStateException("Must set attenuationBucketThresholdDb");
            if (attenuationBucketWeights == null)
                throw new IllegalStateException("Must set attenuationBucketWeights");
            DailySummariesConfig config = new DailySummariesConfig();
            config.reportTypeWeights = Arrays.asList(reportTypeWeights);
            config.infectiousnessWeights = Arrays.asList(infectiousnessWeights);
            config.attenuationBucketThresholdDb = attenuationBucketThresholdDb;
            config.attenuationBucketWeights = attenuationBucketWeights;
            config.daysSinceExposureThreshold = daysSinceExposureThreshold;
            config.minimumWindowScore = minimumWindowScore;
            return config;
        }

        /**
         * See {@link #getAttenuationBucketThresholdDb()} and {@link #getAttenuationBucketWeights()}
         */
        public DailySummariesConfigBuilder setAttenuationBuckets(List<Integer> thresholds, List<Double> weights) {
            attenuationBucketThresholdDb = new ArrayList<>(thresholds);
            attenuationBucketWeights = new ArrayList<>(weights);

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Call builder.setAttenuationBucketThresholdDb(...) with exactly 3 threshold values (in dB, e.g. [30, 40, 60]) before build()
  2. Check every required builder setter is invoked; set weights after thresholds so both validations pass
  3. If building conditionally, ensure the threshold branch is always executed

Example fix

// before
DailySummariesConfig config = new DailySummariesConfig.Builder()
    .setReportTypeWeights(...)
    .build();
// after
DailySummariesConfig config = new DailySummariesConfig.Builder()
    .setAttenuationBucketThresholdDb(Arrays.asList(30, 40, 60))
    .setAttenuationBucketWeights(...)
    .setReportTypeWeights(...)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

List<Integer> thresholds = Arrays.asList(30, 40, 60);
if (builder == null || thresholds == null || thresholds.size() != 3) {
    throw new IllegalStateException("attenuationBucketThresholdDb must be set (3 values)");
}
DailySummariesConfig config = builder
    .setAttenuationBucketThresholdDb(thresholds)
    .build();

Try / catch

try {
    DailySummariesConfig config = builder.build();
} catch (IllegalStateException e) {
    Log.w(TAG, "Incomplete DailySummariesConfig: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling DailySummariesConfig.Builder.build() without first calling setAttenuationBucketThresholdDb(List<Integer>) on the builder.

Common situations: Developers assemble a DailySummariesConfig but omit the threshold list because other builder fields (reportTypeWeights, infectiousnessWeights) have defaults filled with zeros, making it easy to assume thresholds are optional too.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/29a16cfea31ab735. Report an issue: GitHub.