{"record":{"id":"e047b12da9503edf","repo":"Mintplex-Labs/anything-llm","slug":"could-not-refresh-user","errorCode":null,"errorMessage":"Could not refresh user.","messagePattern":"Could not refresh user\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/models/system.js","lineNumber":160,"sourceCode":"      .then((res) => {\n        if (!res.ok) throw new Error(\"Could not validate login.\");\n        return res.json();\n      })\n      .then((res) => res)\n      .catch((e) => {\n        return { valid: false, message: e.message };\n      });\n  },\n  /**\n   * Refreshes the user object from the session.\n   * @returns {Promise<{success: boolean, user: Object | null, message: string | null}>}\n   */\n  refreshUser: () => {\n    return fetch(`${API_BASE}/system/refresh-user`, {\n      headers: baseHeaders(),\n    })\n      .then((res) => {\n        if (!res.ok) throw new Error(\"Could not refresh user.\");\n        return res.json();\n      })\n      .catch((e) => {\n        return { success: false, user: null, message: e.message };\n      });\n  },\n  recoverAccount: async function (username, recoveryCodes) {\n    return await fetch(`${API_BASE}/system/recover-account`, {\n      method: \"POST\",\n      headers: baseHeaders(),\n      body: JSON.stringify({ username, recoveryCodes }),\n    })\n      .then(async (res) => {\n        const data = await res.json();\n        if (!res.ok) {\n          throw new Error(data.message || \"Error recovering account.\");\n        }\n        return data;","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/frontend/src/models/system.js#L142-L178","documentation":"Thrown by System.refreshUser on a non-2xx GET to /api/system/refresh-user. It re-fetches the current session's user object. baseHeaders() supplies the Bearer token. The .catch() returns {success:false, user:null, message:e.message}, so a failed refresh effectively logs the user out from the UI's perspective.","triggerScenarios":"Calling refreshUser() when the Bearer token in localStorage has expired (401/403), when the session was invalidated server-side, or when the user record was deleted between token issue and refresh.","commonSituations":"Token TTL elapsed mid-session; an admin revoked the user; the database user table was modified externally; clock skew between client and server rejects the token.","solutions":["Trigger a re-login flow when success===false and message indicates auth failure.","Confirm localStorage AUTH_TOKEN is still present and not corrupted.","Check server session/token configuration and TTL.","Verify the /system/refresh-user route is registered in the current backend version (it was added after early versions)."],"exampleFix":"// before\nconst { user } = await System.refreshUser();\n\n// after (handle forced logout)\nconst res = await System.refreshUser();\nif (!res.success) {\n  await handleLogout();\n  navigate(\"/login\");\n  return;\n}\nsetUser(res.user);","handlingStrategy":"validation","validationCode":"function hasFreshToken() {\n  return !!window.localStorage.getItem(\"anythingllm_authToken\");\n}\n// if (!hasFreshToken()) skip refreshUser and route to login.","typeGuard":"/** @param {any} r @returns {r is {success:boolean, user:Object|null}} */\nfunction isRefreshResult(r) {\n  return r != null && typeof r.success === \"boolean\" && (r.user === null || typeof r.user === \"object\");\n}","tryCatchPattern":"const res = await System.refreshUser();\nif (!isRefreshResult(res) || !res.success) {\n  await handleLogout();\n  navigate(\"/login\");\n}","preventionTips":["Call refreshUser only when a token is present.","Treat success===false as a session-ending condition.","Avoid spamming refreshUser in a tight loop."],"tags":["network","auth","session"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}