{"record":{"id":"f879c562da19b447","repo":"QuantumNous/new-api","slug":"invalid-passkey-response","errorCode":null,"errorMessage":"Invalid Passkey response","messagePattern":"Invalid Passkey response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/features/auth/sign-in/components/user-auth-form.tsx","lineNumber":285,"sourceCode":"        begin.data?.options ?? begin.data\n      )\n      const flowToken = begin.data?.flow_token\n      if (!flowToken) {\n        throw new Error(t('Login flow expired. Please sign in again.'))\n      }\n\n      const credential = (await navigator.credentials.get({\n        publicKey,\n      })) as PublicKeyCredential | null\n\n      if (!credential) {\n        toast.info(t('Passkey login was cancelled'))\n        return\n      }\n\n      const assertion = buildAssertionResult(credential)\n      if (!assertion) {\n        throw new Error(t('Invalid Passkey response'))\n      }\n\n      const finish = await finishPasskeyLogin(flowToken, assertion)\n      if (!finish.success) {\n        if (getServerErrorMessageKey(finish)) return\n        throw new Error(finish.message || t('Failed to complete Passkey login'))\n      }\n\n      if (!isAuthBundle(finish.data)) {\n        throw new Error(t('Missing user data from Passkey login response'))\n      }\n\n      await handleLoginSuccess(finish.data, redirectTo)\n      toast.success(t('Signed in with Passkey'))\n    } catch (error: unknown) {\n      if (getServerErrorMessageKey(error)) return\n      if (error instanceof DOMException && error.name === 'NotAllowedError') {\n        toast.info(t('Passkey login was cancelled or timed out'))","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/auth/sign-in/components/user-auth-form.tsx#L267-L303","documentation":"Thrown in the Passkey sign-in flow when buildAssertionResult(credential) returns a falsy result — the browser returned a PublicKeyCredential, but the helper could not extract/serialize the assertion fields (authenticatorData, clientDataJSON, signature, userHandle) into the finish payload.","triggerScenarios":"navigator.credentials.get resolves with a credential whose response is missing expected fields or has unexpected types, so buildAssertionResult's extraction/validation fails and returns null/undefined.","commonSituations":"Browser quirk or extension interfering with WebAuthn; a hybrid/phone authenticator returning an assertion shape the serializer does not handle; version change in buildAssertionResult's expectations.","solutions":["Log the credential and credential.response keys in the catch path to see which field is missing.","Test with a different authenticator (platform key vs security key vs phone) to isolate authenticator-specific shapes.","Extend buildAssertionResult to handle the observed shape (e.g. optional userHandle) rather than returning null.","As a user workaround, retry or fall back to password login."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isAuthenticatorAssertion(cred: PublicKeyCredential | null): cred is PublicKeyCredential & {\n  response: AuthenticatorAssertionResponse & { userHandle?: ArrayBuffer | null }\n} {\n  return cred !== null && 'response' in cred &&\n    typeof (cred.response as AuthenticatorAssertionResponse).authenticatorData === 'string'\n}","tryCatchPattern":"try {\n  const assertion = buildAssertionResult(credential)\n  if (!assertion) throw new Error(t('Invalid Passkey response'))\n} catch (error) {\n  if (getServerErrorMessageKey(error)) return\n  // DOMException NotAllowedError is cancellation; anything else: offer password fallback\n}","preventionTips":["Unit-test buildAssertionResult against platform, security-key, and hybrid authenticator fixtures","Treat missing optional fields (userHandle) as absent, not fatal"],"tags":["passkey","webauthn","assertion","browser-compat"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}