Reset password validation errors (uppercase/lowercase/number) not displayed on admin Reset Password page
Node Version
24.14.0
Package Manager
npm
Package Manager Version
11.71.0
Strapi Version
5.52.2
Operating System
Docker/Podman/LXC (gcr.io/distroless/nodejs24-debian13)
Database
PostgreSQL 16.2
Javascript or Typescript
Typescript
Bug Description
On the admin panel's "Reset Password" page (/auth/reset-password, reached via the forgot-password email link), only the "password too short" (min 8 characters) validation error is displayed. Validation errors for missing lowercase letter, missing uppercase letter, or missing number are silently swallowed and never shown to the user.
By contrast, the same password strength rules on the logged-in "Profile" page's Change Password form display correctly.
Root cause
In packages/core/admin/admin/src/pages/Auth/components/ResetPassword.tsx, the lowercase/uppercase/number yup .test() calls pass an incorrectly nested message descriptor:
.test(
'lowercase',
{
message: {
id: 'components.Input.error.contain.lowercase',
defaultMessage: 'Password must contain at least 1 lowercase letter',
},
},
(value) => (value ? /[a-z]/.test(value) : true)
)
yup's ValidationError.message becomes this object as-is, so the error gets stored as { message: { id, defaultMessage } } instead of { id, defaultMessage }. Field.Error / formatMessage() expects the descriptor directly ({ id, defaultMessage }), so it cannot resolve the message and nothing is rendered.
The correct pattern is used in packages/core/admin/admin/src/pages/Settings/pages/Users/utils/validation.ts (COMMON_USER_SCHEMA, used by the Profile page):
.test(
'lowercase',
{
id: 'components.Input.error.contain.lowercase',
defaultMessage: 'Password must contain at least one lowercase character',
},
(value) => (value ? /[a-z]/.test(value) : true)
)
This regression appears to have been introduced by #24538, which fixed the raw-regex-in-error-message issue (#24528) for validation.ts and added a workaround in Register.tsx's submit handler to normalize both message shapes, but did not apply the same fix (schema format or handler workaround) to ResetPassword.tsx. As a result, ResetPassword.tsx still uses the old, incorrectly nested .test() message shape, and unlike Register.tsx, has no fallback handling to normalize it before rendering.
Steps to Reproduce
- Trigger a password reset email and open the "Reset Password" link to reach
/auth/reset-password. - Enter a password that is 8+ characters long but missing an uppercase letter, lowercase letter, or number (e.g.
password123is missing uppercase, orPASSWORD123is missing lowercase). - Submit the form.
- Observe that no validation error is shown for the missing character class, even though the request is blocked.
Expected Behavior
All password validation errors (minimum length, lowercase, uppercase, number, confirm-password mismatch) should be displayed on the Reset Password page, consistent with the Profile page's Change Password form.
Code Snippets
See "Root cause" section above for the relevant excerpts from ResetPassword.tsx and validation.ts.
Additional information
Related: #24528, #24538 (this PR appears to have introduced the regression by fixing validation.ts and Register.tsx but missing ResetPassword.tsx). This is a resubmission of #27693, which was auto-closed because the confirmation checklist checkboxes were not checked in the original submission.
Confirmation Checklist
- I have checked the existing issues for duplicates.
- I agree to follow this project's Code of Conduct.
Source: strapi/strapi