{"record":{"id":"eca22a5728f8f799","repo":"QuantumNous/new-api","slug":"failed-to-load-login-sessions","errorCode":null,"errorMessage":"Failed to load login sessions","messagePattern":"Failed to load login sessions","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/features/profile/components/login-sessions-card.tsx","lineNumber":70,"sourceCode":"} from '../api'\nimport { LoginSessionDialogs } from './login-session-dialogs'\nimport { LoginSessionItem } from './login-session-item'\n\nconst sessionQueryKey = ['profile', 'login-sessions'] as const\n\nexport function LoginSessionsCard() {\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n  const queryClient = useQueryClient()\n  const [revokeTarget, setRevokeTarget] = useState<LoginSession | null>(null)\n  const [confirmOthers, setConfirmOthers] = useState(false)\n\n  const sessionsQuery = useQuery({\n    queryKey: sessionQueryKey,\n    queryFn: async () => {\n      const response = await getLoginSessions()\n      if (!response.success) {\n        throw new Error(response.message || t('Failed to load login sessions'))\n      }\n      return response.data ?? []\n    },\n  })\n\n  const revokeMutation = useMutation({\n    mutationFn: async (sid: string) => {\n      const response = await revokeLoginSession(sid)\n      if (!response.success) {\n        throw new Error(response.message || t('Failed to sign out session'))\n      }\n      return sid\n    },\n    onSuccess: async (sid) => {\n      const revokedCurrent = sessionsQuery.data?.some(\n        (session) => session.sid === sid && session.current\n      )\n      setRevokeTarget(null)","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/profile/components/login-sessions-card.tsx#L52-L88","documentation":"Thrown inside the react-query queryFn of the login-sessions card when getLoginSessions() resolves with success=false. The thrown message becomes the query error rendered by the card; on success it defaults to an empty session list.","triggerScenarios":"Opening the profile page's login sessions card while the sessions endpoint fails: 401 from an expired session, 403 when the feature is disabled by policy, or a backend error listing sessions from the token/session store.","commonSituations":"Current session expired so every profile query 401s; session-management feature disabled in system settings; Redis/session store down on the backend; backend version without the sessions route.","solutions":["Refresh the page / re-login — expired-token 401 is the most common cause","Confirm the login-session feature is enabled in admin system settings","Check backend health of the session store (Redis) if the endpoint 500s","Call getLoginSessions' endpoint directly and read the message field for the precise reason"],"exampleFix":"// before\nconst response = await getLoginSessions()\nif (!response.success) {\n  throw new Error(response.message || t('Failed to load login sessions'))\n}\nreturn response.data ?? []\n// after - treat 401 explicitly so the app can route to login\nconst response = await getLoginSessions()\nif (!response.success) {\n  if (isAuthError(response)) {\n    navigate('/login', { state: { from: location.pathname } })\n    return []\n  }\n  throw new Error(response.message || t('Failed to load login sessions'))\n}\nreturn response.data ?? []","handlingStrategy":"try-catch","validationCode":"// no client preconditions beyond auth; ensure the query is gated on an authenticated session\nenabled: isAuthenticated","typeGuard":null,"tryCatchPattern":"// inside queryFn\nconst response = await getLoginSessions()\nif (!response.success) {\n  throw new Error(response.message || t('Failed to load login sessions'))\n}\nreturn response.data ?? []\n// card renders query.error?.message when present","preventionTips":["Enable the query only for authenticated users to avoid guaranteed 401s","Surface react-query error state in the card UI rather than hiding it","On 401-type messages, redirect to login instead of showing a dead card"],"tags":["api-error","sessions","react-query","profile","auth"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}