microg/GmsCore · error · IllegalStateException

deleteAll=true but keys are provided

Error message

deleteAll=true but keys are provided

What it means

DeleteBytesRequest.Builder.build() performs the same mutual-exclusivity check as the constructor: if setDeleteAll(true) was called while keyList is non-empty, build() throws IllegalStateException. This is the builder-time guard so the invalid state never reaches the constructor.

Source

Thrown at play-services-auth-blockstore/src/main/java/com/google/android/gms/auth/blockstore/DeleteBytesRequest.java:105

    /**
     * A builder for {@link DeleteBytesRequest} objects.
     */
    public static class Builder {
        private final List<String> keyList = new ArrayList<>();
        private boolean deleteAll = false;

        /**
         * Constructor for the {@link DeleteBytesRequest.Builder} class.
         */
        public Builder() {
        }

        /**
         * Builds and returns the {@link DeleteBytesRequest} object.
         */
        public DeleteBytesRequest build() {
            if (deleteAll && !keyList.isEmpty()) {
                throw new IllegalStateException("deleteAll=true but keys are provided");
            }
            return new DeleteBytesRequest(new ArrayList<>(keyList), deleteAll);
        }

        /**
         * Sets whether or not all app's Block Store data should be deleted.
         * <p>
         * The default is {@code false}.
         * <p>
         * Note that if {@code deleteAll} is set to true, then you should NOT set any other deletion criterion, e.g. {@code keys} should be empty. Otherwise, an
         * IllegalStateException will be thrown.
         */
        public Builder setDeleteAll(boolean deleteAll) {
            this.deleteAll = deleteAll;
            return this;
        }

        /**

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Call keyList.clear() / remove setKeys calls, or don't call setDeleteAll(true) — pick one deletion mode.
  2. Run the builder twice in different branches: one branch builds a keys-only request, the other builds deleteAll(true) with no keys.
  3. Validate the intent before building: if wiping all data, construct via DeleteBytesRequest.builder().setDeleteAll(true).build() only.

Example fix

// before
builder.setKeys(keys).setDeleteAll(true).build();
// after
if (deleteAll) {
    req = DeleteBytesRequest.builder().setDeleteAll(true).build();
} else {
    req = DeleteBytesRequest.builder().setKeys(keys).build();
}
Defensive patterns

Strategy: validation

Validate before calling

if (deleteAll && !keyList.isEmpty()) { /* fix before build() */ keyList.clear(); }

Try / catch

try { req = builder.build(); } catch (IllegalStateException e) { log.error("Invalid DeleteBytesRequest: " + e.getMessage()); }

Prevention

When it happens

Trigger: Chaining DeleteBytesRequest.builder().setKeys(...)...setDeleteAll(true).build() — any builder invocation that combines a non-empty keyList with deleteAll=true.

Common situations: Copying settings from an existing builder or request and turning on deleteAll without clearing keys; calling setDeleteAll(true) after adding keys in conditional code paths.

Related errors


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