{"record":{"id":"2fdead9ee6bcbfd7","repo":"microg/GmsCore","slug":"data-err","errorCode":"DATA_ERR","errorMessage":"The request options are not valid","messagePattern":"The request options are not valid","errorType":"error_code","errorClass":"RequestHandlingException","httpStatus":null,"severity":"error","filePath":"play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/RequestHandling.kt","lineNumber":42,"sourceCode":"import org.microg.gms.fido.core.transport.Transport\nimport org.microg.gms.utils.*\nimport java.net.HttpURLConnection\nimport java.security.MessageDigest\n\nprivate const val TAG = \"Fido\"\n\nclass RequestHandlingException(val errorCode: ErrorCode, message: String? = null) : Exception(message)\nclass MissingPinException(message: String? = null): Exception(message)\nclass WrongPinException(message: String? = null): Exception(message)\n\ndata class CredentialUserInfo(val credential: String, val userJson: String, val transport: Transport, val timestamp: Long)\nenum class RequestOptionsType { REGISTER, SIGN }\n\nval RequestOptions.registerOptions: PublicKeyCredentialCreationOptions\n    get() = when (this) {\n        is BrowserPublicKeyCredentialCreationOptions -> publicKeyCredentialCreationOptions\n        is PublicKeyCredentialCreationOptions -> this\n        else -> throw RequestHandlingException(DATA_ERR, \"The request options are not valid\")\n    }\n\nval RequestOptions.signOptions: PublicKeyCredentialRequestOptions\n    get() = when (this) {\n        is BrowserPublicKeyCredentialRequestOptions -> publicKeyCredentialRequestOptions\n        is PublicKeyCredentialRequestOptions -> this\n        else -> throw RequestHandlingException(DATA_ERR, \"The request options are not valid\")\n    }\n\nval RequestOptions.type: RequestOptionsType\n    get() = when (this) {\n        is PublicKeyCredentialCreationOptions, is BrowserPublicKeyCredentialCreationOptions -> REGISTER\n        is PublicKeyCredentialRequestOptions, is BrowserPublicKeyCredentialRequestOptions -> SIGN\n        else -> throw RequestHandlingException(INVALID_STATE_ERR)\n    }\n\nval RequestOptions.webAuthnType: String\n    get() = when (type) {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/RequestHandling.kt#L24-L60","documentation":"The RequestOptions.registerOptions extension unwraps a WebAuthn/FIDO registration request into PublicKeyCredentialCreationOptions. It only accepts BrowserPublicKeyCredentialCreationOptions (unwrapping its inner options) or a plain PublicKeyCredentialCreationOptions; anything else throws RequestHandlingException with code DATA_ERR and message 'The request options are not valid'. This rejects mismatched option types (e.g. a sign/get request passed where a create/register request is expected).","triggerScenarios":"Passing a PublicKeyCredentialRequestOptions, BrowserPublicKeyCredentialRequestOptions, or any other RequestOptions subtype to code that reads .registerOptions (the FIDO register/create pipeline).","commonSituations":"Client code confusing the two WebAuthn ceremonies — calling navigator.credentials.get() options through the register path or vice versa; deserializing option bundles into the wrong class; third-party intents whose extras do not parse into either registration options class.","solutions":["Pass PublicKeyCredentialCreationOptions or BrowserPublicKeyCredentialCreationOptions to the registration API","Inspect the actual runtime class of the RequestOptions before use (options is PublicKeyCredentialCreationOptions) and route register vs sign accordingly","If options come from an intent/JSON payload, fix deserialization so registration requests map to the creation-options class","Catch RequestHandlingException and map DATA_ERR to a clear client error explaining the options type was wrong"],"exampleFix":"// before\nval creation = options.registerOptions // throws DATA_ERR if options is a sign request\n\n// after\nval creation = when (options) {\n    is BrowserPublicKeyCredentialCreationOptions -> options.publicKeyCredentialCreationOptions\n    is PublicKeyCredentialCreationOptions -> options\n    else -> return Result.failure(RequestHandlingException(DATA_ERR, \"Expected registration options\"))\n}","handlingStrategy":"type-guard","validationCode":"when (options) {\n    is BrowserPublicKeyCredentialCreationOptions, is PublicKeyCredentialCreationOptions -> handleRegister(options)\n    else -> failWith(DATA_ERR, \"registration options required\")\n}","typeGuard":"fun RequestOptions.isRegistrationOptions(): Boolean =\n    this is BrowserPublicKeyCredentialCreationOptions || this is PublicKeyCredentialCreationOptions","tryCatchPattern":"try {\n    val creation = options.registerOptions\n} catch (e: RequestHandlingException) {\n    if (e.code == DATA_ERR) return badRequest(\"expected registration options\")\n    throw e\n}","preventionTips":["Route register vs sign by RequestOptions.type before unwrapping","Never reuse one options object across both WebAuthn ceremonies","Verify deserialization maps registration payloads to creation-options classes"],"tags":["android","fido","webauthn","passkeys","type-mismatch"],"backgroundTag":"type-mismatch","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"}