{"record":{"id":"3392072860da01c9","repo":"microg/GmsCore","slug":"no-non-synthetic-fields-were-found","errorCode":null,"errorMessage":"No non-synthetic fields were found","messagePattern":"No non-synthetic fields were found","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java","lineNumber":68,"sourceCode":"        // https://www.jacoco.org/jacoco/trunk/doc/faq.html\n\n        @Nullable\n        Field field = null;\n\n        for (Field currentField : fields) {\n            if (currentField.isSynthetic()) {\n                continue;\n            }\n\n            if (field == null) {\n                field = currentField;\n            } else {\n                throw new IllegalArgumentException(\"Too many non-synthetic fields were found\");\n            }\n        }\n\n        if (field == null) {\n            throw new IllegalArgumentException(\"No non-synthetic fields were found\");\n        }\n\n        if (!field.isAccessible()) {\n            field.setAccessible(true);\n            try {\n                return field.get(binder);\n            } catch (NullPointerException localNullPointerException) {\n                throw new IllegalArgumentException(\"Binder object is null.\",\n                        localNullPointerException);\n            } catch (IllegalArgumentException localIllegalArgumentException) {\n                throw new IllegalArgumentException(\"remoteBinder is the wrong class.\",\n                        localIllegalArgumentException);\n            } catch (IllegalAccessException localIllegalAccessException) {\n                throw new IllegalArgumentException(\"Could not access the field in remoteBinder.\",\n                        localIllegalAccessException);\n            }\n        } else {\n            throw new IllegalArgumentException();","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-basement/src/main/java/com/google/android/gms/dynamic/ObjectWrapper.java#L50-L86","documentation":"After skipping synthetic (instrumentation-added, e.g. JaCoCo $jacocoData) fields, ObjectWrapper.unwrap requires exactly one real field to hold the wrapped object. If none remains, it throws IllegalArgumentException('No non-synthetic fields were found').","triggerScenarios":"unwrap() called on a binder class whose only declared fields are synthetic — commonly a JaCoCo-instrumented build where $jacocoData is filtered out, an empty mock/proxy subclass, or a wrapper class whose payload field was stripped by proguard/R8.","commonSituations":"Running code under JaCoCo coverage where the remote binder class got instrumented; obfuscation removing the wrapper's field; mocks standing in for IObjectWrapper in production paths.","solutions":["Exclude com.google.android.gms.** from JaCoCo/proguard/R8 instrumentation and shrinking (keepclassmembers for the wrapper field)","Ensure the binder is a genuine ObjectWrapper remote binder created by ObjectWrapper.wrap","Verify no test/instrumentation agent is transforming the class at runtime","Pass the wrapped object directly if you have it, avoiding the binder round-trip"],"exampleFix":"// before\nObject v = ObjectWrapper.unwrap(binder); // fails under JaCoCo\n// after\nif (binder instanceof ObjectWrapper) {\n    Object v = ObjectWrapper.unwrapTyped(binder, Object.class);\n} else {\n    Object v = binder; // already local\n}","handlingStrategy":"try-catch","validationCode":"IBinder b = wrapper.asBinder();\nboolean hasReal = false;\nfor (Field f : b.getClass().getDeclaredFields()) {\n    if (!f.isSynthetic() && !f.getName().startsWith(\"$jacoco\")) { hasReal = true; break; }\n}\nif (!hasReal) { /* reject: only synthetic fields */ }","typeGuard":null,"tryCatchPattern":"try {\n    T value = ObjectWrapper.unwrapTyped(wrapper, T.class);\n} catch (IllegalArgumentException e) {\n    // JaCoCo/proguard stripped the field — use local object instead\n}","preventionTips":["Exclude com.google.android.gms.** from JaCoCo instrumentation","Add proguard keep rules for com.google.android.gms.dynamic.**","If the wrapped object is local, skip the binder unwrap entirely"],"tags":["android","reflection","jacoco","proguard"],"backgroundTag":"type-mismatch","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}