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
- Only unwrap IObjectWrapper instances produced by ObjectWrapper.wrap in the same library version
- Align play-services-basement versions across producer and consumer
- Keep the wrapper class single-field: exclude com.google.android.gms.dynamic.** from transformations that add fields (e.g., JaCoCo-like instrumentation, DI frameworks)
- 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
- Don't subclass or modify the gms ObjectWrapper/binder classes
- Align library versions between the code that wraps and the code that unwraps
- Avoid passing arbitrary Binder objects where an IObjectWrapper is expected
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
- No fields were found
- Binder object is null.
- remoteBinder is the wrong class.
- suggested UID [
- suggested PID [
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/50d882da937dbd03.
Report an issue: GitHub.