microg/GmsCore · error · IllegalStateException

Missing required properties: scopes

Error message

Missing required properties: scopes

What it means

RevokeAccessRequest.Builder.build() requires both scopes and account. When scopes is null (setScopes never called), build() throws IllegalStateException 'Missing required properties: scopes' before even checking account. This guards against sending an access-revocation request without the OAuth scopes to revoke.

Source

Thrown at play-services-auth/src/main/java/com/google/android/gms/auth/api/identity/RevokeAccessRequest.java:59

        this.scopes = scopes;
        this.account = account;
        this.sessionId = sessionId;
    }

    /**
     * Returns a new {@link RevokeAccessRequest.Builder}.
     */
    @NonNull
    public static RevokeAccessRequest.Builder builder() {
        return new Builder() {
            private List<Scope> scopes;
            private Account account;
            private String sessionId;

            @NonNull
            @Override
            public RevokeAccessRequest build() {
                if (scopes == null) throw new IllegalStateException("Missing required properties: scopes");
                if (account == null) throw new IllegalStateException("Missing required properties: account");
                return new RevokeAccessRequest(scopes, account, sessionId);
            }

            @NonNull
            @Override
            public Builder setAccount(@NonNull Account account) {
                this.account = account;
                return this;
            }

            @NonNull
            @Override
            public Builder setScopes(@NonNull List<Scope> scopes) {
                this.scopes = scopes;
                return this;
            }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Call setScopes(...) with the list of scopes to revoke before build().
  2. Derive scopes from the stored credential/token rather than external config to avoid empty values.
  3. Guard: if scopes == null || scopes.isEmpty(), abort the revocation flow with a user-visible error instead of building.

Example fix

// before
RevokeAccessRequest req = RevokeAccessRequest.builder().setAccount(account).build();
// after
RevokeAccessRequest req = RevokeAccessRequest.builder()
    .setScopes(scopes) // e.g. Collections.singletonList(OAuth2.SCOPE_PROFILE)
    .setAccount(account)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (scopes == null || scopes.isEmpty()) { abortRevocation("no scopes to revoke"); return; }

Try / catch

try { req = RevokeAccessRequest.builder().setScopes(scopes).setAccount(account).build(); } catch (IllegalStateException e) { log.warn("RevokeAccessRequest incomplete: " + e.getMessage()); }

Prevention

When it happens

Trigger: RevokeAccessRequest.builder()...build() where setScopes(...) was never invoked (or was passed conditions that skipped it).

Common situations: Building the request from a scopes list that was empty/null due to a failed config load; forgetting setScopes because account setup was the focus; refactors moving scope collection elsewhere.

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/9e2cd6b3eef814a9. Report an issue: GitHub.