Mintplex-Labs/anything-llm · error · Error
Invalid password.
Error message
Invalid password.
What it means
Thrown by resetPassword when the trimmed new password is empty. The function trims _newPassword and rejects an empty result before any token lookup or DB write. It is the first precondition in the reset flow and prevents sending an empty password onward to User.update.
Source
Thrown at server/utils/PasswordRecovery/index.js:73
const index = unmatchedHashes.findIndex((hash) =>
bcrypt.compareSync(code, hash)
);
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, {View on GitHub (pinned to 526360e320)
Solutions
- Ensure the client sends a non-empty password (after trim) in the newPassword field.
- Add client-side validation so the reset form cannot be submitted with an empty password.
- If calling resetPassword programmatically, guard with if (!newPassword?.trim()) before invoking.
Example fix
// before await resetPassword(token, " ", " "); // after await resetPassword(token, "Str0ng!Pass", "Str0ng!Pass");
Defensive patterns
Strategy: validation
Validate before calling
function isValidNewPassword(p) {
return typeof p === "string" && p.trim().length > 0;
}
if (!isValidNewPassword(newPassword)) {
return { success: false, message: "Password cannot be empty." };
} Type guard
function isNonEmptyString(v) {
return typeof v === "string" && v.trim().length > 0;
} Try / catch
try {
return await resetPassword(token, newPassword, confirmPassword);
} catch (e) {
if (/Invalid password/i.test(e.message)) {
return { success: false, message: "Please provide a non-empty password." };
}
throw e;
} Prevention
- Validate non-empty password on the client before submit.
- Treat empty password as a 400, not a thrown exception, in the route handler.
- Trim whitespace consistently on both client and server.
When it happens
Trigger: Client submits an empty or whitespace-only password field; a malformed request body where the password value is an empty or whitespace-only string (note String(undefined).trim() yields 'undefined', so this specifically requires an empty or whitespace-only string); frontend sends the field before the user typed anything.
Common situations: Browser autofill leaving the field blank; automated test sending an empty string; a curl/Postman request missing the newPassword parameter.
Related errors
- Passwords do not match
- 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/460a757d67548802.
Report an issue: GitHub.