QuantumNous/new-api · error · Error

Unable to parse Passkey login options from response

Error message

Unable to parse Passkey login options from response

What it means

Thrown by prepareCredentialRequestOptions in the passkey lib when the backend's login-options payload has none of the recognized carriers (publicKey, PublicKey, response, Response) for the WebAuthn PublicKeyCredentialRequestOptions. It mirrors the registration parser: without a challenge/options object, navigator.credentials.get cannot be invoked.

Source

Thrown at web/src/lib/passkey.ts:163

  }

  return publicKey
}

/**
 * Prepare credential request options returned by the backend.
 */
export function prepareCredentialRequestOptions(
  payload: any
): PublicKeyCredentialRequestOptions {
  const options =
    payload?.publicKey ??
    payload?.PublicKey ??
    payload?.response ??
    payload?.Response

  if (!options) {
    throw new Error('Unable to parse Passkey login options from response')
  }

  const publicKey: PublicKeyCredentialRequestOptions & Record<string, any> = {
    ...options,
    challenge: base64UrlToArrayBuffer(options.challenge),
  }

  if (Array.isArray(options.allowCredentials)) {
    publicKey.allowCredentials = options.allowCredentials.map((item: any) => ({
      ...item,
      id: base64UrlToArrayBuffer(item.id),
    }))
  }

  return publicKey
}

/**

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Inspect the begin-passkey-login response in the network tab; confirm where the options object (with challenge) actually sits.
  2. Ensure the begin request includes credentials/CSRF token so it returns real options rather than an auth-error envelope.
  3. Align the parser with the backend contract or fix the backend to return options under publicKey; cover with a unit test using a captured fixture.
  4. Catch the error and show 'Passkey login unavailable' with a password-login fallback.
Defensive patterns

Strategy: type-guard

Validate before calling

if (!begin.success || !begin.data?.options) {
  // do not call prepareCredentialRequestOptions; surface begin.message instead
}

Type guard

function hasRequestOptions(payload: any): boolean {
  return Boolean(payload?.publicKey ?? payload?.PublicKey ?? payload?.response ?? payload?.Response)
}

Try / catch

try {
  const publicKey = prepareCredentialRequestOptions(begin.data?.options ?? begin.data)
} catch (error) {
  if (/Unable to parse Passkey login options/.test(error.message)) {
    toast.error(t('Passkey login unavailable')); return // password login remains
  }
}

Prevention

When it happens

Trigger: beginPasskeyLogin succeeds but begin.data is undefined/an error body, or the options object is nested under a field the parser does not know; also when callers pass begin.data?.options ?? begin.data and both are empty.

Common situations: Login-begin endpoint returning success:true with empty data; API contract change moving options; proxy stripping the response body; session/CSRF failure returning an HTML page parsed into an unexpected object.

Understand the failure class

Related errors


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