QuantumNous/new-api · error · Error

Unable to parse Passkey registration options from response

Error message

Unable to parse Passkey registration options from response

What it means

Thrown by prepareCredentialCreationOptions in the passkey lib when the backend's registration-options payload contains none of the recognized shapes: top-level publicKey, PublicKey, response, or Response. The WebAuthn navigator.credentials.create call needs a PublicKeyCredentialCreationOptions object; without one, registration cannot proceed and the parser refuses to guess.

Source

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

    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/g, '')
}

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

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

  const publicKey: PublicKeyCredentialCreationOptions & Record<string, any> = {
    ...options,
    challenge: base64UrlToArrayBuffer(options.challenge),
    user: {
      ...options.user,
      id: base64UrlToArrayBuffer(options.user?.id),
    },
  }

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

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Log the payload keys at the call site and compare with the four accepted fields (publicKey/PublicKey/response/Response).
  2. Check the registration-begin request actually succeeded before parsing — a failed begin with success:false must not reach this function.
  3. If the backend nests options differently, extend the lookup (or better, fix the backend contract) and add a fixture test for that shape.
  4. Handle the throw with a user-facing 'Passkey registration failed, try again' message.

Example fix

// before
const publicKey = prepareCredentialCreationOptions(begin.data)

// after — guard the envelope before parsing
if (!begin.success || !begin.data) {
  throw new Error(begin.message || 'Failed to start Passkey registration')
}
const publicKey = prepareCredentialCreationOptions(begin.data)
Defensive patterns

Strategy: type-guard

Validate before calling

if (!payload || !(payload.publicKey ?? payload.PublicKey ?? payload.response ?? payload.Response)) {
  // show 'Passkey registration unavailable' and fall back; do not call the parser
}

Type guard

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

Try / catch

try {
  const publicKey = prepareCredentialCreationOptions(payload)
} catch (error) {
  if (/Unable to parse Passkey registration options/.test(error.message)) {
    // log payload shape, show retry UI, keep password/OTP signup available
  }
}

Prevention

When it happens

Trigger: Calling prepareCredentialCreationOptions(payload) where payload is null/undefined, an error envelope ({success:false}), or a registration-begin response whose options live under a new/unexpected key.

Common situations: Backend returns {success:false} (session expired before registration start) and the caller passes res.data (undefined) through; API version change renaming the options field; response wrapped one level deeper than expected.

Understand the failure class

Related errors


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