microg/GmsCore · error · IllegalArgumentException
No fields were found
Error message
No fields were found
What it means
ObjectWrapper.unwrap reflects over the underlying binder's class to find the wrapped object's field. It throws IllegalArgumentException('No fields were found') when the binder's class declares zero fields, which means the object passed is not a real ObjectWrapper remote binder.
Source
Thrown at play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java:46
public ObjectWrapper(T t) {
this.t = t;
}
@Nullable
public static Object unwrap(IObjectWrapper obj) {
if (obj == null) {
return null;
}
if (obj instanceof ObjectWrapper) {
return ((ObjectWrapper) obj).t;
}
IBinder binder = obj.asBinder();
Field[] fields = binder.getClass().getDeclaredFields();
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");
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Pass only IObjectWrapper instances created via ObjectWrapper.wrap(obj), not mocks or hand-built implementations
- Disable proguard minification/obfuscation for com.google.android.gms.dynamic.** (keep class members)
- Align play-services-basement versions across all modules
- In tests, use ObjectWrapper.wrap(realObject) instead of Mockito.mock(IObjectWrapper.class)
Example fix
// before IObjectWrapper w = Mockito.mock(IObjectWrapper.class); MyType t = ObjectWrapper.unwrapTyped(w, MyType.class); // throws // after IObjectWrapper w = ObjectWrapper.wrap(new MyTypeImpl()); MyType t = ObjectWrapper.unwrapTyped(w, MyType.class);
Defensive patterns
Strategy: try-catch
Validate before calling
if (wrapper == null) return null; IBinder b = wrapper.asBinder(); if (b == null || b.getClass().getDeclaredFields().length == 0) return null; // would throw
Type guard
boolean isWrappable(IObjectWrapper w) {
if (w == null) return false;
IBinder b = w.asBinder();
return b != null && b.getClass().getDeclaredFields().length >= 1;
} Try / catch
try {
T value = ObjectWrapper.unwrapTyped(wrapper, T.class);
} catch (IllegalArgumentException e) {
Log.w(TAG, "unwrap failed", e);
value = null;
} Prevention
- Only unwrap wrappers created by ObjectWrapper.wrap
- Never use Mockito mocks for IObjectWrapper in production code paths
- Keep gms dynamic classes excluded from code coverage instrumentation
- Pin a single play-services-basement version across modules
When it happens
Trigger: Calling ObjectWrapper.unwrap() on an IObjectWrapper whose asBinder() class has no declared fields — typically a Mockito-style mock, a lambda/proxy subclass, or an ObjectWrapper created by a different/older library version whose internal layout changed.
Common situations: Unit tests injecting mocked IObjectWrapper instances into production code; proguard/R8 renaming or stripping the field; mixed play-services versions in a multi-module build.
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
- Too many non-synthetic 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/5111a5b1c929b4ab.
Report an issue: GitHub.