{"record":{"id":"20da64157e960901","repo":"microg/GmsCore","slug":"checkin-disabled","errorCode":null,"errorMessage":"Checkin disabled","messagePattern":"Checkin disabled","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt","lineNumber":33,"sourceCode":"import androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.LifecycleService\nimport androidx.lifecycle.lifecycleScope\nimport org.microg.gms.checkin.CheckinPreferences\nimport org.microg.gms.checkin.CheckinService\nimport org.microg.gms.checkin.LastCheckinInfo\nimport org.microg.gms.common.ForegroundServiceContext\nimport org.microg.gms.common.PackageUtils\nimport org.microg.gms.gcm.GcmConstants.*\nimport org.microg.gms.ui.AskPushPermission\nimport java.util.concurrent.atomic.AtomicBoolean\nimport kotlin.coroutines.resume\nimport kotlin.coroutines.suspendCoroutine\n\nprivate const val TAG = \"GmsGcmRegister\"\n\nprivate suspend fun ensureCheckinIsUpToDate(context: Context) {\n    if (!CheckinPreferences.isEnabled(context)) throw RuntimeException(\"Checkin disabled\")\n    val lastCheckin = LastCheckinInfo.read(context).lastCheckin\n    if (lastCheckin < System.currentTimeMillis() - CheckinService.MAX_VALID_CHECKIN_AGE) {\n        val resultData: Bundle = suspendCoroutine { continuation ->\n            val intent = Intent(context, CheckinService::class.java)\n            val continued = AtomicBoolean(false)\n            intent.putExtra(CheckinService.EXTRA_RESULT_RECEIVER, object : ResultReceiver(null) {\n                override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {\n                    if (continued.compareAndSet(false, true)) continuation.resume(resultData ?: Bundle.EMPTY)\n                }\n            })\n            ForegroundServiceContext(context).startService(intent)\n            Handler().postDelayed({\n                if (continued.compareAndSet(false, true)) continuation.resume(Bundle.EMPTY)\n            }, 10000L)\n        }\n        if (resultData.getLong(CheckinService.EXTRA_NEW_CHECKIN_TIME, 0L) + lastCheckin == 0L) {\n            throw RuntimeException(\"No checkin available\")\n        }","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt#L15-L51","documentation":"Configuration gate in PushRegisterService.ensureCheckinIsUpToDate: check-in is disabled in microG settings (CheckinPreferences.isEnabled is false), so device registration cannot proceed and the pre-registration gate aborts with this RuntimeException.","triggerScenarios":"Thrown at play-services-core/src/main/kotlin/org/microg/gms/gcm/PushRegisterService.kt:33 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Enable device check-in in microG settings","Catch the exception and report ERROR_SERVICE_NOT_AVAILABLE / not-registered to the caller"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}