microg/GmsCore · error · RuntimeException

oauthToken is null

Error message

oauthToken is null

What it means

requestOauthToken performs an auth request via AuthManager and returns the resulting auth token. If the auth response contains no token (auth == null), it throws RuntimeException("oauthToken is null") — meaning authentication completed (or silently failed) without yielding a token for the requested service scope.

Source

Thrown at play-services-core/src/main/kotlin/com/google/android/gms/family/v2/manage/FamilyExtensions.kt:126

    val deviceInfo = DeviceInfo.build {
        moduleVersion(FAMILY_MANAGEMENT_MODULE_VERSION)
        clientType(7)
        moduleInfo(CallerInfo.build { appId(appId) })
    }
    return RequestContext.build {
        deviceInfo(deviceInfo)
        familyExperimentOverrides("")
        moduleSet("")
    }
}

suspend fun requestOauthToken(context: Context, accountName: String, service: String): String {
    val authResponse = withContext(Dispatchers.IO) {
        AuthManager(
            context, accountName, Constants.GMS_PACKAGE_NAME, service
        ).apply { isPermitted = true }.requestAuth(true)
    }
    return authResponse.auth ?: throw RuntimeException("oauthToken is null")
}

fun GetFamilyResponse.parseToMemberDataModels(context: Context, accountName: String, configResponse: GetFamilyManagementConfigResponse?): MutableList<MemberDataModel> {
    val inviteSlotSize = configResponse?.let {
        val inviteOption = it.configMain?.familyOption?.find { option -> option.optionId == FAMILY_OPTION_INVITE_ID }
        val inviteSlotsContent = inviteOption?.optionContents?.find { c -> c.optId == FAMILY_OPTION_INVITE_TITLE_ID }?.content
        inviteSlotsContent?.let { content -> Regex("\\d+").find(content)?.value?.toIntOrNull() ?: 0 } ?: 0
    } ?: 0
    val memberDataModels = mutableListOf<MemberDataModel>()
    memberDataList.map {
        MemberDataModel().apply {
            memberId = it.memberId ?: ""
            profilePhotoUrl = it.profile?.profilePhotoUrl ?: it.profile?.defaultPhotoUrl ?: ""
            displayName = it.profile?.displayName ?: it.profile?.email ?: ""
            email = it.profile?.email ?: ""
            hohGivenName = it.hohGivenName ?: ""
            role = it.role?.value ?: FamilyRole.UNCONFIRMED_MEMBER.value
            roleName = it.role?.name ?: FamilyRole.UNCONFIRMED_MEMBER.name

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Verify the account exists in microG and can authenticate (check microG account settings / Google sign-in)
  2. Check the AuthResponse for error details from requestAuth before reading auth
  3. Retry after confirming network connectivity to Google auth servers
  4. Catch the RuntimeException in callers (e.g. FamilyViewModel already wraps it in runCatching) and surface a sign-in-required state

Example fix

// before
val token = requestOauthToken(context, account, SERVICE_FAMILY_SCOPE)
// after
val token = try {
    requestOauthToken(context, account, SERVICE_FAMILY_SCOPE)
} catch (e: RuntimeException) {
    Log.w(TAG, "oauth token unavailable", e); return
}
Defensive patterns

Strategy: try-catch

Validate before calling

val accounts = AccountManager.get(context).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE)
require(accounts.any { it.name == accountName }) { "account not signed in: $accountName" }

Type guard

fun Context.hasSignedInAccount(accountName: String): Boolean =
    AccountManager.get(this).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE).any { it.name == accountName }

Try / catch

try {
    val token = requestOauthToken(context, accountName, scope)
} catch (e: RuntimeException) {
    showSignInRequired()
}

Prevention

When it happens

Trigger: AuthManager.requestAuth returns a response whose auth field is null: the account is not signed in, the requested service/scope is not permitted for the account, network/server issues returned an empty token, or isPermitted=true was granted but the backend refused to issue a token.

Common situations: Family management screens in microG when the configured Google account is not properly registered with microG's auth backend, or the FAMILY_SCOPE service string is rejected server-side.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/53d1836791a5125b. Report an issue: GitHub.