{"record":{"id":"57e5381fe3b7ba5b","repo":"QuantumNous/new-api","slug":"passkey-verification-is-not-supported-in-this-envi","errorCode":null,"errorMessage":"Passkey verification is not supported in this environment","messagePattern":"Passkey verification is not supported in this environment","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/features/auth/secure-verification/api.ts","lineNumber":131,"sourceCode":"  })\n\n  if (!res.data?.success) {\n    throw new Error(res.data?.message || i18next.t('Verification failed'))\n  }\n  if (!res.data.data?.proof_token) {\n    throw new Error(i18next.t('Verification proof was not returned'))\n  }\n  return res.data.data\n}\n\n/**\n * Perform Passkey verification flow.\n */\nasync function verifyPasskey(\n  scope: SecurityProofScope\n): Promise<SecurityProof> {\n  if (typeof navigator === 'undefined' || !navigator.credentials) {\n    throw new Error(\n      i18next.t('Passkey verification is not supported in this environment')\n    )\n  }\n\n  try {\n    const beginResponse = await beginPasskeyVerification(scope)\n    if (!beginResponse.success) {\n      throw new Error(\n        beginResponse.message || i18next.t('Failed to start verification')\n      )\n    }\n\n    const publicKey = prepareCredentialRequestOptions(\n      beginResponse.data?.options ?? beginResponse.data\n    )\n    const flowToken = beginResponse.data?.flow_token\n    if (!flowToken) {\n      throw new Error(i18next.t('Verification flow expired'))","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/auth/secure-verification/api.ts#L113-L149","documentation":"Thrown by verifyPasskey() when navigator is undefined or navigator.credentials is missing, i.e. the WebAuthn API is not available in the current browsing context. WebAuthn requires a secure context and a reasonably modern browser, so this fires before any network or credential operation.","triggerScenarios":"Running the app over plain http on a non-localhost host; very old browsers without WebAuthn; non-browser JS environments (SSR, webview shells) where navigator.credentials is absent; incognito/embedded browsers that disable the API.","commonSituations":"Dev deployment accessed via http://192.168.x.x from a phone; corporate webviews; testing in an old Evergreen/Safari version; iframe embedding without allow='publickey-credentials-get'.","solutions":["Serve the site over HTTPS (or use http://localhost, which is a secure context).","Feature-detect WebAuthn before showing the passkey option and hide/disable it when unsupported.","Upgrade to a browser that supports WebAuthn (all evergreen browsers since ~2018-2020).","If embedded in an iframe, add allow=\"publickey-credentials-get\" to the iframe element."],"exampleFix":"// before\n<button onClick={() => verify('passkey', scope)}>Use Passkey</button>\n\n// after\nconst passkeySupported =\n  typeof navigator !== 'undefined' &&\n  !!navigator.credentials &&\n  !!window.PublicKeyCredential\n\n{passkeySupported && (\n  <button onClick={() => verify('passkey', scope)}>Use Passkey</button>\n)}","handlingStrategy":"validation","validationCode":"const passkeyAvailable =\n  typeof navigator !== 'undefined' &&\n  !!navigator.credentials &&\n  !!window.PublicKeyCredential\nif (!passkeyAvailable) {\n  hidePasskeyOption() // fall back to 2FA code UI\n}","typeGuard":"const supportsWebAuthn = (): boolean =>\n  typeof navigator !== 'undefined' &&\n  'credentials' in navigator &&\n  typeof window.PublicKeyCredential !== 'undefined'","tryCatchPattern":null,"preventionTips":["Serve over HTTPS; only http://localhost is a secure context","Feature-detect before rendering the passkey button","Add allow=\"publickey-credentials-get\" when embedding in iframes"],"tags":["passkey","webauthn","browser-support","secure-context"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}