{"record":{"id":"03fcf1cfc83b9878","repo":"QuantumNous/new-api","slug":"missing-user-data-from-passkey-login-response","errorCode":null,"errorMessage":"Missing user data from Passkey login response","messagePattern":"Missing user data from Passkey login response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/features/auth/sign-in/components/user-auth-form.tsx","lineNumber":295,"sourceCode":"\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'))\n      } else if (error instanceof Error) {\n        toast.error(error.message)\n      } else {\n        toast.error(t('Passkey login failed'))\n      }\n    } finally {\n      setIsPasskeyLoading(false)\n    }\n  }\n","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/auth/sign-in/components/user-auth-form.tsx#L277-L313","documentation":"Thrown in the Passkey sign-in flow when finishPasskeyLogin returns success:true but finish.data fails the isAuthBundle check — the server verified the credential yet did not return a complete auth bundle (token, session, user). It is the Passkey analogue of the password-login bundle guard and prevents storing a half-formed session.","triggerScenarios":"Finish-passkey-login responds {success:true} with data missing required bundle fields (null data, no session, no user, no access_token).","commonSituations":"Backend bug or contract drift on the passkey finish endpoint; partial deploy mismatching frontend bundle expectations; response mangled by an interceptor or proxy.","solutions":["Capture the finish response body and diff its data against isAuthBundle's required fields.","Fix the backend finish handler to emit the full AuthBundle on success (same shape as password login).","Verify no interceptor rewrites the response; deploy frontend/backend together.","User workaround: sign in with password (which exercises the same bundle path) to confirm whether it is passkey-specific."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// reuse isAuthBundle as the single authority for post-login payloads\nif (finish.success && !isAuthBundle(finish.data)) { /* contract violation path */ }","tryCatchPattern":"try {\n  if (!isAuthBundle(finish.data)) throw new Error(t('Missing user data from Passkey login response'))\n} catch (error) {\n  if (getServerErrorMessageKey(error)) return\n  toast.error(error instanceof Error ? error.message : t('Passkey login failed'))\n}","preventionTips":["Make the passkey finish endpoint reuse the same bundle serializer as password login","Cover all login entry points with one shared bundle contract test"],"tags":["passkey","auth-bundle","type-guard","api-contract"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}