From 93bd0f24fe779cc7c02cfa8df2a71a7eb8efd455 Mon Sep 17 00:00:00 2001 From: "Adolfo R. Brandes" Date: Thu, 5 Mar 2026 16:20:34 -0300 Subject: [PATCH] fix: prioritize registration errors over inline validations in backendValidations Registration errors from form submission (e.g., "password too similar to username") were being masked by stale inline validation results. The backendValidations memo checked state.validations first, which was set during on-blur field validation with no errors, causing it to never reach the registrationError branch. Co-Authored-By: Claude Opus 4.6 --- .../components/RegisterContext.test.tsx | 31 +++++++++++++++++++ src/register/components/RegisterContext.tsx | 8 ++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/register/components/RegisterContext.test.tsx b/src/register/components/RegisterContext.test.tsx index 38b66c1b..4813b44e 100644 --- a/src/register/components/RegisterContext.test.tsx +++ b/src/register/components/RegisterContext.test.tsx @@ -322,6 +322,37 @@ describe('RegisterContext', () => { }); }); + it('should prioritize registrationError over validations for backendValidations', () => { + const { result } = renderHook(() => useRegisterContext(), { wrapper }); + + // Simulate inline validation (on blur) setting validations + act(() => { + result.current.setValidationsSuccess({ + validationDecisions: { + password: '', + username: '', + }, + }); + }); + + expect(result.current.backendValidations).toEqual({ + password: '', + username: '', + }); + + // Simulate form submission returning a registration error + act(() => { + result.current.setRegistrationError({ + errorCode: [{ userMessage: 'validation-error' }], + password: [{ userMessage: 'The password is too similar to the username.' }], + }); + }); + + expect(result.current.backendValidations).toEqual({ + password: 'The password is too similar to the username.', + }); + }); + it('should return null for backendValidations when neither validations nor registrationError exist', () => { const { result } = renderHook(() => useRegisterContext(), { wrapper }); expect(result.current.backendValidations).toBe(null); diff --git a/src/register/components/RegisterContext.tsx b/src/register/components/RegisterContext.tsx index 91ef2166..8d6a78cd 100644 --- a/src/register/components/RegisterContext.tsx +++ b/src/register/components/RegisterContext.tsx @@ -139,10 +139,6 @@ export const RegisterProvider: FC = ({ children }) => { }, []); const backendValidations = useMemo(() => { - if (state.validations) { - return state.validations.validationDecisions; - } - if (state.registrationError && Object.keys(state.registrationError).length > 0) { const fields = Object.keys(state.registrationError).filter( (fieldName) => !(['errorCode', 'usernameSuggestions'].includes(fieldName)), @@ -155,6 +151,10 @@ export const RegisterProvider: FC = ({ children }) => { return validationDecisions; } + if (state.validations) { + return state.validations.validationDecisions; + } + return null; }, [state.validations, state.registrationError]);