microg/GmsCore · error · IllegalStateException

Must set daysSinceOnsetToInfectiousness

Error message

Must set daysSinceOnsetToInfectiousness

What it means

DiagnosisKeysDataMapping.Builder.build() requires daysSinceOnsetToInfectiousness to be set; it maps days-since-onset offsets to infectiousness levels when diagnosis keys are uploaded. The builder throws IllegalStateException to stop a mapping object with no map from being submitted to the Exposure Notification API.

Source

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

     */
    public int getReportTypeWhenMissing() {
        return reportTypeWhenMissing;
    }

    /**
     * A builder for {@link DiagnosisKeysDataMapping}.
     */
    public static class DiagnosisKeysDataMappingBuilder {
        private final static int MAX_DAYS = 29;
        private List<Integer> daysSinceOnsetToInfectiousness;
        @ReportType
        private int reportTypeWhenMissing = ReportType.UNKNOWN;
        @Infectiousness
        private Integer infectiousnessWhenDaysSinceOnsetMissing;

        public DiagnosisKeysDataMapping build() {
            if (daysSinceOnsetToInfectiousness == null)
                throw new IllegalStateException("Must set daysSinceOnsetToInfectiousness");
            if (reportTypeWhenMissing == ReportType.UNKNOWN)
                throw new IllegalStateException("Must set reportTypeWhenMissing");
            if (infectiousnessWhenDaysSinceOnsetMissing == null)
                throw new IllegalStateException("Must set infectiousnessWhenDaysSinceOnsetMissing");
            DiagnosisKeysDataMapping mapping = new DiagnosisKeysDataMapping();
            mapping.daysSinceOnsetToInfectiousness = new ArrayList<>(daysSinceOnsetToInfectiousness);
            mapping.reportTypeWhenMissing = reportTypeWhenMissing;
            mapping.infectiousnessWhenDaysSinceOnsetMissing = infectiousnessWhenDaysSinceOnsetMissing;
            return mapping;
        }

        public DiagnosisKeysDataMappingBuilder setDaysSinceOnsetToInfectiousness(Map<Integer, Integer> daysSinceOnsetToInfectiousness) {
            if (daysSinceOnsetToInfectiousness.size() > MAX_DAYS)
                throw new IllegalArgumentException("daysSinceOnsetToInfectiousness exceeds " + MAX_DAYS + " days");
            Integer[] values = new Integer[MAX_DAYS];
            Arrays.fill(values, 0);
            for (Map.Entry<Integer, Integer> entry : daysSinceOnsetToInfectiousness.entrySet()) {
                if (entry.getKey() > 14) throw new IllegalArgumentException("invalid day since onset");

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Call setDaysSinceOnsetToInfectiousness with a map of day offsets (-14..14) to @Infectiousness values before build()
  2. If you intentionally want defaults, still provide the map (empty or fully populated) so validation passes
  3. Ensure the mapping initialization code path always runs (e.g. first-launch setup)

Example fix

// before
DiagnosisKeysDataMapping mapping = new DiagnosisKeysDataMapping.Builder().build();
// after
Map<Integer, Integer> days = new HashMap<>();
days.put(-14, Infectiousness.HIGH);
days.put(0, Infectiousness.HIGH);
days.put(14, Infectiousness.HIGH);
DiagnosisKeysDataMapping mapping = new DiagnosisKeysDataMapping.Builder()
    .setDaysSinceOnsetToInfectiousness(days)
    .setReportTypeWhenMissing(ReportType.CONFIRMED_TEST)
    .setInfectiousnessWhenDaysSinceOnsetMissing(Infectiousness.STANDARD)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (daysSinceOnsetToInfectiousness == null) {
    daysSinceOnsetToInfectiousness = Collections.emptyMap();
}
DiagnosisKeysDataMapping mapping = new DiagnosisKeysDataMapping.Builder()
    .setDaysSinceOnsetToInfectiousness(daysSinceOnsetToInfectiousness)
    .setReportTypeWhenMissing(ReportType.CONFIRMED_TEST)
    .setInfectiousnessWhenDaysSinceOnsetMissing(Infectiousness.STANDARD)
    .build();

Try / catch

try {
    DiagnosisKeysDataMapping mapping = mappingBuilder.build();
} catch (IllegalStateException e) {
    Log.w(TAG, "Incomplete DiagnosisKeysDataMapping: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling DiagnosisKeysDataMapping.Builder.build() without calling setDaysSinceOnsetToInfectiousness(Map<Integer,Integer>).

Common situations: App authors assemble the mapping partially during onboarding configuration and leave the map unset, or assume the builder supplies a default mapping.

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/1ed90b21ef5681d4. Report an issue: GitHub.