{"record":{"id":"c18bdca6911f13d7","repo":"Mintplex-Labs/anything-llm","slug":"data-message-error-recovering-account","errorCode":null,"errorMessage":"data.message || \"Error recovering account.\"","messagePattern":"data\\.message \\|\\| \"Error recovering account\\.\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/models/system.js","lineNumber":176,"sourceCode":"    })\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;\n      })\n      .catch((e) => {\n        console.error(e);\n        return { success: false, error: e.message };\n      });\n  },\n  resetPassword: async function (token, newPassword, confirmPassword) {\n    return await fetch(`${API_BASE}/system/reset-password`, {\n      method: \"POST\",\n      headers: baseHeaders(),\n      body: JSON.stringify({ token, newPassword, confirmPassword }),\n    })\n      .then(async (res) => {\n        const data = await res.json();\n        if (!res.ok) {\n          throw new Error(data.message || \"Error resetting password.\");","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/frontend/src/models/system.js#L158-L194","documentation":"Thrown by System.recoverAccount on a non-2xx POST to /api/system/recover-account with body {username, recoveryCodes}. Unlike most routes, it reads res.json() first and uses data.message (the server's specific reason) as the error string, falling back to 'Error recovering account.' The .catch() returns {success:false, error:e.message}.","triggerScenarios":"Calling recoverAccount(username, codes) when recovery codes are wrong/exhausted, when the username does not exist, when recovery is disabled in system settings, or when a code has already been consumed (single-use).","commonSituations":"User mistypes a recovery code; codes were already used during a prior recovery; multi-user mode is off so /system/recover-account is unavailable; the recovery code set was regenerated and old codes are invalid.","solutions":["Show data.message to the user — it carries the server's specific recovery error.","Confirm recovery codes are single-use and have not been spent.","Verify the account exists and that recovery is enabled in system settings.","If codes are exhausted, fall back to an admin-assisted reset."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function validRecoveryInput(username, codes) {\n  return typeof username === \"string\" && username.length > 0\n    && Array.isArray(codes) && codes.length > 0\n    && codes.every(c => typeof c === \"string\");\n}","typeGuard":"/** @param {any} r @returns {r is {success:boolean}} */\nfunction isRecoveryResult(r) { return r != null && typeof r.success === \"boolean\"; }","tryCatchPattern":"const res = await System.recoverAccount(username, codes);\nif (!isRecoveryResult(res) || !res.success) {\n  showError(res.error || \"Recovery failed\");\n}","preventionTips":["Remember recovery codes are single-use — do not retry the same set.","Surface the server message (res.error) verbatim.","Rate-limit recovery attempts client-side."],"tags":["network","auth","recovery","account"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}