QuantumNous/new-api · error · Error

Invalid Passkey response

Error message

Invalid Passkey response

What it means

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.

Source

Thrown at web/src/features/auth/sign-in/components/user-auth-form.tsx:285

        begin.data?.options ?? begin.data
      )
      const flowToken = begin.data?.flow_token
      if (!flowToken) {
        throw new Error(t('Login flow expired. Please sign in again.'))
      }

      const credential = (await navigator.credentials.get({
        publicKey,
      })) as PublicKeyCredential | null

      if (!credential) {
        toast.info(t('Passkey login was cancelled'))
        return
      }

      const assertion = buildAssertionResult(credential)
      if (!assertion) {
        throw new Error(t('Invalid Passkey response'))
      }

      const finish = await finishPasskeyLogin(flowToken, assertion)
      if (!finish.success) {
        if (getServerErrorMessageKey(finish)) return
        throw new Error(finish.message || t('Failed to complete Passkey login'))
      }

      if (!isAuthBundle(finish.data)) {
        throw new Error(t('Missing user data from Passkey login response'))
      }

      await handleLoginSuccess(finish.data, redirectTo)
      toast.success(t('Signed in with Passkey'))
    } catch (error: unknown) {
      if (getServerErrorMessageKey(error)) return
      if (error instanceof DOMException && error.name === 'NotAllowedError') {
        toast.info(t('Passkey login was cancelled or timed out'))

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Log the credential and credential.response keys in the catch path to see which field is missing.
  2. Test with a different authenticator (platform key vs security key vs phone) to isolate authenticator-specific shapes.
  3. Extend buildAssertionResult to handle the observed shape (e.g. optional userHandle) rather than returning null.
  4. As a user workaround, retry or fall back to password login.
Defensive patterns

Strategy: type-guard

Type guard

function isAuthenticatorAssertion(cred: PublicKeyCredential | null): cred is PublicKeyCredential & {
  response: AuthenticatorAssertionResponse & { userHandle?: ArrayBuffer | null }
} {
  return cred !== null && 'response' in cred &&
    typeof (cred.response as AuthenticatorAssertionResponse).authenticatorData === 'string'
}

Try / catch

try {
  const assertion = buildAssertionResult(credential)
  if (!assertion) throw new Error(t('Invalid Passkey response'))
} catch (error) {
  if (getServerErrorMessageKey(error)) return
  // DOMException NotAllowedError is cancellation; anything else: offer password fallback
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/f879c562da19b447. Report an issue: GitHub.