microg/GmsCore · error · IllegalArgumentException
remoteBinder is the wrong class.
Error message
remoteBinder is the wrong class.
What it means
During ObjectWrapper.unwrap, field.get(binder) threw an IllegalArgumentException, rethrown as 'remoteBinder is the wrong class.' The single field's value does not match what the caller expects — i.e., the object stored in the wrapper is not of the expected type for the requested unwrap.
Source
Thrown at play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java:79
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) {
throw new IllegalArgumentException("Could not access the field in remoteBinder.",
localIllegalAccessException);
}
} else {
throw new IllegalArgumentException();
}
}
@Nullable
public static <T> T unwrapTyped(IObjectWrapper obj, Class<T> clazz) {
try {
return clazz.cast(unwrap(obj));
} catch (ClassCastException e) {
return null;
}
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Verify the type passed to unwrapTyped matches what the producer actually wrapped
- Align play-services versions on both sides of the binder transaction
- Catch IllegalArgumentException and fall back or re-wrap locally
- If you control the producer, wrap the exact expected type: ObjectWrapper.wrap(expectedInstance)
Example fix
// before
Foo foo = ObjectWrapper.unwrapTyped(w, Foo.class);
// after
Foo foo;
try {
foo = ObjectWrapper.unwrapTyped(w, Foo.class);
} catch (IllegalArgumentException e) {
Log.w(TAG, "Wrapped object not a Foo", e);
foo = null;
} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the concrete type before unwrapping
Object raw = null;
try { raw = ObjectWrapper.unwrap(wrapper); } catch (IllegalArgumentException ignored) {}
if (!(raw instanceof ExpectedType)) { /* wrong class — bail out */ } Try / catch
try {
T value = ObjectWrapper.unwrapTyped(wrapper, T.class);
} catch (IllegalArgumentException e) {
Log.w(TAG, "Wrapped object is not " + T.class.getName(), e);
value = null;
} Prevention
- Match the wrapped type between producer and consumer
- Keep play-services versions aligned on both sides of the transaction
- Wrap exactly the type the consumer will request
When it happens
Trigger: unwrapTyped(w, T.class) where the wrapper actually holds an instance of a different class than T (or the field value's class isn't assignable); cross-version wrapper layout change making the reflective field return a different object.
Common situations: Mixed play-services versions between producer and consumer; caller assuming a specific wrapped type that the producer never put there; misconfigured binder transaction returning the wrong remote object.
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
- Too many non-synthetic fields were found
- Binder object is null.
- suggested UID [
- suggested PID [
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/a359732fa9ebde27.
Report an issue: GitHub.