microg/GmsCore · error · IllegalArgumentException

Too many non-synthetic fields were found

Error message

Too many non-synthetic fields were found

What it means

ObjectWrapper.unwrap expects the remote binder class to expose exactly one non-synthetic field (the wrapped object). If reflection finds two or more non-synthetic fields it cannot determine which one holds the payload and throws IllegalArgumentException('Too many non-synthetic fields were found').

Source

Thrown at play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java:63

        if (fields.length < 1) {
            throw new IllegalArgumentException("No fields were found");
        }

        // Ignore synthetic field(s) from JaCoCo or elsewhere
        // https://www.jacoco.org/jacoco/trunk/doc/faq.html

        @Nullable
        Field field = null;

        for (Field currentField : fields) {
            if (currentField.isSynthetic()) {
                continue;
            }

            if (field == null) {
                field = currentField;
            } else {
                throw new IllegalArgumentException("Too many non-synthetic fields were found");
            }
        }

        if (field == null) {
            throw new IllegalArgumentException("No non-synthetic fields were found");
        }

        if (!field.isAccessible()) {
            field.setAccessible(true);
            try {
                return field.get(binder);
            } catch (NullPointerException localNullPointerException) {
                throw new IllegalArgumentException("Binder object is null.",
                        localNullPointerException);
            } catch (IllegalArgumentException localIllegalArgumentException) {
                throw new IllegalArgumentException("remoteBinder is the wrong class.",
                        localIllegalArgumentException);
            } catch (IllegalAccessException localIllegalAccessException) {

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Only unwrap IObjectWrapper instances produced by ObjectWrapper.wrap in the same library version
  2. Align play-services-basement versions across producer and consumer
  3. Keep the wrapper class single-field: exclude com.google.android.gms.dynamic.** from transformations that add fields (e.g., JaCoCo-like instrumentation, DI frameworks)
  4. Re-wrap the object locally instead of unwrapping a foreign binder

Example fix

// before
Object value = ObjectWrapper.unwrap(foreignBinder);
// after
if (foreignBinder instanceof MyConcreteType) {
    Object value = ((MyConcreteType) foreignBinder).getValue();
} else {
    Object value = ObjectWrapper.unwrapTyped(ObjectWrapper.wrap(foreignBinder), Object.class);
}
Defensive patterns

Strategy: try-catch

Validate before calling

IBinder b = wrapper.asBinder();
int real = 0;
for (Field f : b.getClass().getDeclaredFields()) {
    if (!f.isSynthetic() && !f.getName().startsWith("$")) real++;
}
if (real != 1) { /* reject: wrong wrapper class */ }

Try / catch

try {
    T value = ObjectWrapper.unwrapTyped(wrapper, T.class);
} catch (IllegalArgumentException e) {
    // wrapper layout mismatch — treat as absent / re-wrap locally
}

Prevention

When it happens

Trigger: unwrap() called on a binder whose class has multiple real (non-synthetic) fields — i.e., the class is not the single-field ObjectWrapper$* remote wrapper, e.g., some other Binder subclass, a mock with multiple fields, or a different library version's wrapper with a changed layout.

Common situations: Receiving an IObjectWrapper from an app using a different Google Play services version whose wrapper gained fields; passing arbitrary Binder objects; test doubles with extra fields.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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