Mintplex-Labs/anything-llm · error · Error
Passwords do not match
Error message
Passwords do not match
What it means
Thrown by resetPassword when the trimmed new password does not equal the trimmed confirmPassword string. This is a standard confirm-password equality check performed before token lookup and password update. Both values are coerced to strings, so type mismatches alone won't trigger it — only differing content will.
Source
Thrown at server/utils/PasswordRecovery/index.js:75
);
if (index === -1) return false;
unmatchedHashes.splice(index, 1);
return true;
});
if (!validCodes) return { success: false, error: "Invalid recovery codes." };
const { passwordResetToken, error } = await PasswordResetToken.create(
user.id
);
if (!!error) return { success: false, error };
return { success: true, resetToken: passwordResetToken.token };
}
async function resetPassword(token, _newPassword = "", confirmPassword = "") {
const newPassword = String(_newPassword).trim(); // No spaces in passwords
if (!newPassword) throw new Error("Invalid password.");
if (newPassword !== String(confirmPassword))
throw new Error("Passwords do not match");
const resetToken = await PasswordResetToken.findUnique({
token: String(token),
});
if (!resetToken || resetToken.expiresAt < new Date()) {
return { success: false, message: "Invalid reset token" };
}
// JOI password rules will be enforced inside .update.
const { error } = await User.update(resetToken.user_id, {
password: newPassword,
});
// seen_recovery_codes is not publicly writable
// so we have to do direct update here
await User._update(resetToken.user_id, {
seen_recovery_codes: false,
});View on GitHub (pinned to 526360e320)
Solutions
- Re-enter both password fields identically and resubmit.
- Check the client payload includes both newPassword and confirmPassword with matching values.
- Verify the field names sent in the request body exactly match the parameter names the route expects.
- Add a client-side equality check to give immediate feedback before submit.
Example fix
// before await resetPassword(token, "Str0ng!Pass", "Str0ng!Passs"); // after await resetPassword(token, "Str0ng!Pass", "Str0ng!Pass");
Defensive patterns
Strategy: validation
Validate before calling
if (String(newPassword).trim() !== String(confirmPassword).trim()) {
return { success: false, message: "Passwords do not match." };
} Type guard
function passwordsMatch(a, b) {
return typeof a === "string" && typeof b === "string" && a.trim() === b.trim();
} Try / catch
try {
return await resetPassword(token, newPassword, confirmPassword);
} catch (e) {
if (/Passwords do not match/i.test(e.message)) {
return { success: false, message: "Passwords do not match." };
}
throw e;
} Prevention
- Add a client-side equality check with a 'show password' toggle to catch typos.
- Ensure both fields are sent with the exact parameter names the route expects.
- Avoid transforming one field (e.g. hashing) on the client but not the other.
When it happens
Trigger: The two password fields contain different characters after trimming; confirmPassword is undefined (String(undefined)='undefined') while newPassword is a real password; the frontend sent confirmPassword under a different key name.
Common situations: User typo between the two fields; frontend bug only sending one field; client concatenating or transforming one value; copy-paste error.
Related errors
- Invalid password.
- Type "${type}" is not a valid type to sync.
- Invalid link provided
- Invalid source property provided
- No base URL was set.
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/6c5f93909e55f52a.
Report an issue: GitHub.