n8n-io/n8n · warning · BadRequestError
400
400
Error message
Current password is required to change email
What it means
A BadRequestError (HTTP 400) from validateChangingUserEmail when the user is MFA-disabled (mfaEnabled false), has a password set, but providedCurrentPassword is missing or not a string. To change email without 2FA, the user must re-confirm with their current password; omitting it is rejected.
Source
Thrown at packages/cli/src/controllers/me.controller.ts:159
if (!payload.mfaCode) {
throw new BadRequestError('Two-factor code is required to change email');
}
const isMfaCodeValid = await this.mfaService.validateMfa(userId, payload.mfaCode, undefined);
if (!isMfaCodeValid) {
throw new InvalidMfaCodeError();
}
} else {
if (currentUser.password === null) {
this.logger.debug('User with no password changed their email', {
userId: currentUser.id,
payload: payloadWithoutPassword,
});
return;
}
if (!providedCurrentPassword || typeof providedCurrentPassword !== 'string') {
throw new BadRequestError('Current password is required to change email');
}
const isProvidedPasswordCorrect = await this.passwordUtility.compare(
providedCurrentPassword,
currentUser.password,
);
if (!isProvidedPasswordCorrect) {
throw new BadRequestError(
'Unable to update profile. Please check your credentials and try again.',
);
}
}
}
private isUserManagedByEnv(user: User): boolean {
const { instanceSettingsLoader } = this.globalConfig;
return (
instanceSettingsLoader.ownerManagedByEnv &&View on GitHub (pinned to 5ac6606e81)
Solutions
- Include a non-empty currentPassword string in the PATCH /me body when changing email without MFA.
- Add a 'current password' input to the email-change form for non-MFA users.
- Validate typeof currentPassword === 'string' && currentPassword on the client before submit.
Example fix
// before
await api.patch('/me', { email: newEmail });
// after
await api.patch('/me', { email: newEmail, currentPassword: promptPassword() }); Defensive patterns
Strategy: validation
Validate before calling
// Require current password for email change when MFA is off.
if (!me.mfaEnabled && isEmailChange(payload, me.email)) {
if (typeof payload.currentPassword !== 'string' || payload.currentPassword.length === 0) {
throw new Error('Current password is required to change email');
}
} Type guard
function hasCurrentPassword(p: { currentPassword?: string }): p is { currentPassword: string } {
return typeof p.currentPassword === 'string' && p.currentPassword.length > 0;
} Try / catch
try {
await api.patch('/me', { ...payload, currentPassword });
} catch (e) {
if (e.response?.status === 400 && /current password is required/i.test(e.response.data.message)) {
currentPassword = await promptPassword();
await api.patch('/me', { ...payload, currentPassword });
return;
}
throw e;
} Prevention
- Add a current-password field to the email-change form for non-MFA users.
- Validate currentPassword is a non-empty string before submit.
- Do not send null/undefined for required credential fields.
When it happens
Trigger: PATCH /me changing email for a password-based (non-MFA) user where currentPassword is omitted, null, undefined, or a non-string type. The branch is reached because mfaEnabled is false and currentUser.password is non-null.
Common situations: Frontend form omits the current-password field for email change; client serializes the field as null; user leaves the field blank; a script that only sends the new email.
Related errors
- SAML user may not change their email
- Cannot save user <${this.email}>: Provided email is invalid
- Token is required
- ${ssoIdentity.providerType.toUpperCase()} user may not chang
- 403
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/2ef317b72eb91b41.
Report an issue: GitHub.