Mintplex-Labs/anything-llm · error · Error

data.message || "Error recovering account."

Error message

data.message || "Error recovering account."

What it means

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}.

Source

Thrown at frontend/src/models/system.js:176

    })
      .then((res) => {
        if (!res.ok) throw new Error("Could not refresh user.");
        return res.json();
      })
      .catch((e) => {
        return { success: false, user: null, message: e.message };
      });
  },
  recoverAccount: async function (username, recoveryCodes) {
    return await fetch(`${API_BASE}/system/recover-account`, {
      method: "POST",
      headers: baseHeaders(),
      body: JSON.stringify({ username, recoveryCodes }),
    })
      .then(async (res) => {
        const data = await res.json();
        if (!res.ok) {
          throw new Error(data.message || "Error recovering account.");
        }
        return data;
      })
      .catch((e) => {
        console.error(e);
        return { success: false, error: e.message };
      });
  },
  resetPassword: async function (token, newPassword, confirmPassword) {
    return await fetch(`${API_BASE}/system/reset-password`, {
      method: "POST",
      headers: baseHeaders(),
      body: JSON.stringify({ token, newPassword, confirmPassword }),
    })
      .then(async (res) => {
        const data = await res.json();
        if (!res.ok) {
          throw new Error(data.message || "Error resetting password.");

View on GitHub (pinned to 526360e320)

Solutions

  1. Show data.message to the user — it carries the server's specific recovery error.
  2. Confirm recovery codes are single-use and have not been spent.
  3. Verify the account exists and that recovery is enabled in system settings.
  4. If codes are exhausted, fall back to an admin-assisted reset.
Defensive patterns

Strategy: validation

Validate before calling

function validRecoveryInput(username, codes) {
  return typeof username === "string" && username.length > 0
    && Array.isArray(codes) && codes.length > 0
    && codes.every(c => typeof c === "string");
}

Type guard

/** @param {any} r @returns {r is {success:boolean}} */
function isRecoveryResult(r) { return r != null && typeof r.success === "boolean"; }

Try / catch

const res = await System.recoverAccount(username, codes);
if (!isRecoveryResult(res) || !res.success) {
  showError(res.error || "Recovery failed");
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/c18bdca6911f13d7. Report an issue: GitHub.