{"record":{"id":"a9b499c8fa13c882","repo":"microg/GmsCore","slug":"required-caller-information-missing","errorCode":null,"errorMessage":"Required caller information missing","messagePattern":"Required caller information missing","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-core/src/main/java/org/microg/gms/auth/AskPermissionActivity.java","lineNumber":107,"sourceCode":"                callerPid = intent.getIntExtra(KEY_CALLER_PID, 0);\n                fromAccountManager = intent.hasExtra(EXTRA_FROM_ACCOUNT_MANAGER);\n                if (intent.hasExtra(EXTRA_CONSENT_DATA)) {\n                    try {\n                        consentData = ConsentData.ADAPTER.decode(intent.getByteArrayExtra(EXTRA_CONSENT_DATA));\n                    } catch (Exception e) {\n                        Log.w(TAG, \"ConsentData decode failed\", e);\n                    }\n                }\n            }\n            if (accountName != null && accountType != null) {\n                account = new Account(accountName, accountType);\n            }\n        }\n\n        private void verify(Context context) throws Exception {\n            if (accountName == null || accountType == null || account == null) throw new IllegalArgumentException(\"Required account information missing\");\n            if (packageName == null || service == null) throw new IllegalArgumentException(\"Required request information missing\");\n            if (callerUid == 0) throw new IllegalArgumentException(\"Required caller information missing\");\n            PackageUtils.getAndCheckPackage(context, packageName, callerUid, callerPid);\n\n            PackageManager packageManager = context.getPackageManager();\n            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);\n            appLabel = packageManager.getApplicationLabel(applicationInfo);\n            appIcon = packageManager.getApplicationIcon(applicationInfo);\n        }\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.ask_permission);\n        data = new IntentData(getIntent());\n        try {\n            data.verify(this);\n        } catch (Exception e) {\n            Log.w(TAG, \"Verification failed\", e);","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-core/src/main/java/org/microg/gms/auth/AskPermissionActivity.java#L89-L125","documentation":"AskPermissionActivity.verify() validates the extras the activity was launched with before showing the permission consent UI. This IllegalArgumentException is thrown when the callerUid extra is missing or 0, meaning microG cannot identify which app is requesting the account permission. It is a fail-fast guard: without the caller UID the package/UID check (PackageUtils.getAndCheckPackage) cannot run.","triggerScenarios":"Launching AskPermissionActivity via Intent without the callerUid integer extra set (or explicitly setting it to 0), even when accountName, accountType, account, packageName, and service extras are all present.","commonSituations":"Hand-crafted or partially copied auth Intents that mimic Google Play Services' getRequestIntent response; custom account authenticator code that builds the permission Intent manually and forgets to put the calling UID; a third-party client app built against a different protocol version.","solutions":["Set the callerUid extra on the Intent launching AskPermissionActivity, typically from Binder.getCallingUid() in the authenticator's getRequestIntent implementation.","Also verify callerPid is provided, since verify() passes it to PackageUtils.getAndCheckPackage alongside callerUid.","If you control neither side, update the client app to use the standard AccountManager.requestAuthToken flow so microG populates the extras itself."],"exampleFix":"// before\nIntent i = new Intent(\"com.google.android.gms.auth.ASK_PERMISSION\");\ni.putExtra(\"account\", account);\ni.putExtra(\"packageName\", ctx.getPackageName());\n// after\nIntent i = new Intent(\"com.google.android.gms.auth.ASK_PERMISSION\");\ni.putExtra(\"account\", account);\ni.putExtra(\"packageName\", ctx.getPackageName());\ni.putExtra(\"callerUid\", Binder.getCallingUid());\ni.putExtra(\"callerPid\", Binder.getCallingPid());","handlingStrategy":"validation","validationCode":"int callerUid = intent.getIntExtra(\"callerUid\", 0);\nif (callerUid == 0) throw new IllegalStateException(\"callerUid extra required before launching AskPermissionActivity\");","typeGuard":null,"tryCatchPattern":"try { activity.verifyFlow(); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"caller information\")) { /* rebuild intent with Binder.getCallingUid() */ } }","preventionTips":["Always derive callerUid from Binder.getCallingUid() inside the authenticator, never hardcode it.","Include all required extras (callerUid, callerPid) alongside account/packageName/service.","Test the permission flow against a real AccountManager round-trip, not just a hand-built Intent."],"tags":["android","authentication","intent-extras","microg"],"backgroundTag":"missing-required-argument","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}