{"record":{"id":"813c47db6addab8c","repo":"microg/GmsCore","slug":"callingpackagename-is-not-first-party","errorCode":null,"errorMessage":"$callingPackageName is not first-party","messagePattern":"\\$callingPackageName is not first-party","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-core/src/main/kotlin/org/microg/gms/games/FirstPartyGamesService.kt","lineNumber":38,"sourceCode":"import com.google.android.gms.games.client.PlayGamesConsistencyTokens\nimport org.microg.gms.BaseService\nimport org.microg.gms.common.Constants\nimport org.microg.gms.common.GmsService\nimport org.microg.gms.common.GooglePackagePermission\nimport org.microg.gms.common.PackageUtils\nimport org.microg.gms.utils.warnOnTransactionIssues\n\nprivate const val TAG = \"PlayGamesService\"\nprivate val FIRST_PARTY_PACKAGES = setOf(Constants.GMS_PACKAGE_NAME, GAMES_PACKAGE_NAME)\n\nclass FirstPartyGamesService : BaseService(TAG, GmsService.GAMES) {\n    override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {\n        val packageName = PackageUtils.getAndCheckCallingPackageOrImpersonation(this, request.packageName)\n            ?: throw IllegalArgumentException(\"Missing package name\")\n        val callingPackageName = PackageUtils.getCallingPackage(this) ?: packageName\n        if (!PackageUtils.callerHasGooglePackagePermission(this, GooglePackagePermission.GAMES))\n            throw IllegalArgumentException(\"$callingPackageName does not have google games access\")\n        if (callingPackageName !in FIRST_PARTY_PACKAGES) throw IllegalArgumentException(\"$callingPackageName is not first-party\")\n        callback.onPostInitCompleteWithConnectionInfo(\n            CommonStatusCodes.SUCCESS,\n            PlayGamesServiceImpl(this, lifecycle, packageName),\n            ConnectionInfo()\n        )\n    }\n}\n\nclass PlayGamesServiceImpl(val context: Context, val lifecycle: Lifecycle, val packageName: String) : IPlayGamesService.Stub() {\n\n    override fun getGameCollection(callbacks: IPlayGamesCallbacks?, maxResults: Int, gameCollectionType: Int, z: Boolean, forceReload: Boolean) {\n        Log.d(TAG, \"Not yet implemented: getGameCollection($maxResults, $gameCollectionType, $z, $forceReload)\")\n        callbacks?.onData(DataHolder.empty(CommonStatusCodes.SUCCESS))\n    }\n\n    override fun loadGames(callbacks: IPlayGamesCallbacks?, playerId: String?, maxResults: Int, z: Boolean, forceReload: Boolean) {\n        Log.d(TAG, \"Not yet implemented: loadGames($playerId, $maxResults, $z, $forceReload)\")\n        callbacks?.onData(DataHolder.empty(CommonStatusCodes.SUCCESS))","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-core/src/main/kotlin/org/microg/gms/games/FirstPartyGamesService.kt#L20-L56","documentation":"FirstPartyGamesService additionally restricts callers to FIRST_PARTY_PACKAGES (com.google.android.gms and the Games package). If the caller passed the Google-package-permission check but its package name is not in that set, IllegalArgumentException(\"<pkg> is not first-party\") is thrown.","triggerScenarios":"A Google-permission-holding but non-first-party package binding to FirstPartyGamesService — rare, e.g. an internally signed test app or an app with the GAMES permission that is not com.google.android.gms/games.","commonSituations":"Internal Google-signed tools or modified clients hitting the first-party endpoint; misconfigured client pointing at the wrong GmsService variant.","solutions":["Use GamesService or GamesConnectService for non-first-party packages","Ensure the binding package is one of FIRST_PARTY_PACKAGES (com.google.android.gms or the Games package name)","Fix the client config to target the correct service action"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"val firstParty = setOf(Constants.GMS_PACKAGE_NAME, GAMES_PACKAGE_NAME)\nrequire(context.packageName in firstParty) { \"caller must be first-party\" }","typeGuard":null,"tryCatchPattern":"try {\n  firstPartyGamesClient.connect()\n} catch (e: IllegalArgumentException) {\n  if (e.message?.endsWith(\"is not first-party\") == true) {\n    gamesConnectClient.connect()\n  }\n}","preventionTips":["Confirm the binding package is com.google.android.gms or the Games package before using the first-party endpoint","Route other packages to GamesService/GamesConnectService","Keep client service-action configuration correct"],"tags":["play-games","permission-denied","first-party","service-binding"],"backgroundTag":"permission-denied","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"}