Mintplex-Labs/anything-llm · warning
Invalid password.
Error message
Invalid password.
What it means
Message 'Invalid password.' from POST /system/reset-password, arriving as HTTP 500 even though it is a client mistake. resetPassword trims the new password and throws when the result is empty; the endpoint's catch block converts any throw into a 500 JSON response carrying the thrown message verbatim.
Source
Thrown at server/endpoints/system.js:438
"/system/reset-password",
[isMultiUserSetup],
async (request, response) => {
try {
const { token, newPassword, confirmPassword } = reqBody(request);
const { success, message, error } = await resetPassword(
token,
newPassword,
confirmPassword
);
if (success) {
response.status(200).json({ success, message });
} else {
response.status(400).json({ success, error });
}
} catch (error) {
console.error("Error resetting password:", error);
response.status(500).json({ success: false, message: error.message });
}
}
);
app.get(
"/system/system-vectors",
[validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])],
async (request, response) => {
try {
const query = queryParams(request);
const VectorDb = getVectorDbClass();
const vectorCount = !!query.slug
? await VectorDb.namespaceCount(query.slug)
: await VectorDb.totalVectors();
response.status(200).json({ vectorCount });
} catch (e) {
console.error(e.message, e);
response.sendStatus(500).end();View on GitHub (pinned to 20f6d3546c)
Solutions
- Send a non-empty newPassword after trimming
- Note the follow-on rule: the password must also pass the joi-password-complexity check inside User.update (min 8 chars by default, tunable via PASSWORDMINCHAR) or you will get a 400 with that message instead
- In clients, treat a 500 from this endpoint carefully — real server faults and this client error share the status code; branch on the message
Example fix
// before
await api.post('/system/reset-password', {
token, newPassword: ' ', confirmPassword: ' '
}); // 500 { success:false, message:'Invalid password.' }
// after
await api.post('/system/reset-password', {
token, newPassword: 'correct horse battery', confirmPassword: 'correct horse battery'
}); Defensive patterns
Strategy: validation
Validate before calling
// Trim and require a non-empty password before calling the API
const newPassword = String(rawNewPassword ?? '').trim();
if (!newPassword) throw new Error('New password is required');
await api.post('/system/reset-password', { token, newPassword, confirmPassword: newPassword }); Type guard
function isNonEmptyPassword(v) {
return typeof v === 'string' && v.trim().length > 0;
} Prevention
- Disable the submit button until both password fields are non-empty
- Remember this endpoint returns 500 for what are really client errors — branch on message text
- Pre-validate the 8-char (PASSWORDMINCHAR) minimum client-side to avoid the separate 400
When it happens
Trigger: POST /system/reset-password with newPassword omitted, empty, or whitespace-only (e.g. " ") while holding a valid reset token. The empty-check runs before the confirm-password comparison, so confirmPassword is irrelevant here.
Common situations: Form submitted before the new-password field was filled; whitespace-only paste; automated tests sending empty strings and misreading the 500 as a server fault.
Related errors
- Passwords do not match
- Failed to enable multi-user mode.
- click requires <x> <y> coordinates
- type requires <text> argument
- key requires <key> argument (e.g. Enter, Tab, Escape)
AI-assisted analysis of Mintplex-Labs/anything-llm@20f6d3546c (2026-08-18).
Data as JSON: /api/errors/1b2bde00c08dcb4f.
Report an issue: GitHub.