{"record":{"id":"fcd8c29f2ad4046b","repo":"microg/GmsCore","slug":"no-result","errorCode":null,"errorMessage":"No result","messagePattern":"No result","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/ui/hybrid/HybridAuthenticateActivity.kt","lineNumber":175,"sourceCode":"            .setExcludeList(request.excludeList)\n            .build()\n\n        val browserOptions = BrowserPublicKeyCredentialCreationOptions.Builder()\n            .setPublicKeyCredentialCreationOptions(publicKeyCredentialCreationOptions)\n            .setOrigin(\"https://${request.rp.id}\".toUri())\n            .setClientDataHash(request.clientDataHash).build()\n\n        val intent = Intent(this, AuthenticatorActivity::class.java)\n            .putExtra(AuthenticatorActivity.KEY_SOURCE, AuthenticatorActivity.SOURCE_HYBRID)\n            .putExtra(AuthenticatorActivity.KEY_TYPE, AuthenticatorActivity.TYPE_REGISTER)\n            .putExtra(AuthenticatorActivity.KEY_OPTIONS, browserOptions.serializeToBytes())\n\n        val result = suspendCancellableCoroutine { continuation ->\n            waitingLauncherContinuation = continuation\n            waitingLauncher.launch(intent)\n        }\n\n        val resultBytes = result.data?.getByteArrayExtra(FIDO2_KEY_CREDENTIAL_EXTRA) ?: throw RuntimeException(\"No result\")\n        val publicKeyCredential = PublicKeyCredential.deserializeFromBytes(resultBytes)\n        val response = publicKeyCredential.response as? AuthenticatorAttestationResponse? ?: throw RuntimeException(\"Invalid result\")\n        val attestationObject = AttestationObject.decode(response.attestationObject)\n\n        return AuthenticatorMakeCredentialResponse(\n            authData = attestationObject.authData,\n            fmt = attestationObject.fmt,\n            attStmt = attestationObject.attStmt\n        )\n    }\n\n    private suspend fun handleGetAssertion(request: AuthenticatorGetAssertionRequest): AuthenticatorGetAssertionResponse {\n        val publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions.Builder()\n            .setRpId(request.rpId)\n            .setChallenge(request.clientDataHash)\n            .setAllowList(request.allowList)\n            .setRequireUserVerification(request.options?.userVerification?.takeIf { it }?.let { UserVerificationRequirement.REQUIRED })\n            .build()","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/ui/hybrid/HybridAuthenticateActivity.kt#L157-L193","documentation":"In HybridAuthenticateActivity.handleMakeCredential, the activity waits for a nested authenticator activity via suspendCancellableCoroutine; if the launched Intent result carries no FIDO2_KEY_CREDENTIAL_EXTRA byte array, it throws RuntimeException(\"No result\"). The inner activity returned without producing a credential (typically cancelled or failed).","triggerScenarios":"waitingLauncher.launch(intent) returns a result Intent whose data is null or lacks the FIDO2_KEY_CREDENTIAL_EXTRA extra — i.e. the invoked AuthenticatorActivity finished with RESULT_CANCELED or without a credential payload.","commonSituations":"User cancelled the hybrid (caBLE/QR) sign-up flow; the inner activity crashed or timed out; the wrong response code path returned a bare result Intent.","solutions":["Check resultCode for RESULT_OK/RESULT_CANCELED before reading the credential extra","Show a cancellation message and re-launch the flow if the user cancelled","Inspect logs of the nested AuthenticatorActivity for failures that end without setting FIDO2_KEY_CREDENTIAL_EXTRA","Catch the RuntimeException in startHybridConnectionFlow and return a cancelable error to the FIDO client"],"exampleFix":"// before\nval resultBytes = result.data?.getByteArrayExtra(FIDO2_KEY_CREDENTIAL_EXTRA) ?: throw RuntimeException(\"No result\")\n// after\nif (resultCode != RESULT_OK) throw UserCanceledException()\nval resultBytes = result.data?.getByteArrayExtra(FIDO2_KEY_CREDENTIAL_EXTRA)\n    ?: throw RuntimeException(\"No result\")","handlingStrategy":"validation","validationCode":"val resultBytes = result.data?.getByteArrayExtra(FIDO2_KEY_CREDENTIAL_EXTRA)\nif (result == null || resultBytes == null) return null // treat as user-cancel","typeGuard":"fun Intent?.hasCredentialExtra(): Boolean =\n    this?.getByteArrayExtra(FIDO2_KEY_CREDENTIAL_EXTRA) != null","tryCatchPattern":"try {\n    val response = handleMakeCredential()\n} catch (e: RuntimeException) {\n    if (e.message == \"No result\") emit(FidoResult.Canceled) else throw e\n}","preventionTips":["Check resultCode == RESULT_OK before reading extras","Treat missing extras as user cancellation, not a crash","Log inner-activity failures that finish without a credential","Keep the hybrid flow foregrounded so the nested activity is not killed"],"tags":["fido","android","activity-result","cancellation"],"backgroundTag":"empty-result-set","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"}