Episode 2 — React Frontend Architecture NextJS / 2.15 — Advanced Forms and Validation
2.15.d — Error display patterns
Learning outcomes
- Build field-level and form-level error UX that is accessible.
- Map server validation errors to fields deterministically.
- Handle async validation without race conditions and confusing flicker.
Pattern A — inline field errors
- Tie
aria-invalidto truthiness of error state. - Reference error element ids via
aria-describedby. - Keep error text near the field; do not rely on color alone.
Pattern B — error summary at top
Useful for long forms:
- On submit, render a list of links jumping to each invalid field (href
#field-id). - Announce updates for screen readers with
aria-live="polite"for non-critical summaries, orassertiveif you must interrupt (use sparingly).
Pattern C — server errors after submit
Normalize API errors:
export type ApiFieldError = { field: string; message: string; code?: string };
Then:
errors.forEach((e) => setError(e.field as any, { message: e.message }));
Prefer stable code values for i18n.
Async field validation
- Debounce requests.
- Cancel in-flight checks when value changes.
- Show pending state (
validating) distinct from error state.
Field arrays
Display per-index errors (items.2.name) consistently with RHF nested naming.
Appendix — Scenario bank (basic → advanced)
Each scenario is a mini design review: what users see, what breaks, what you change, what you say in an interview. Cover five per day and narrate fixes out loud.
ERR-001 — Error display scenario #1
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
13 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-002 — Error display scenario #2
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
26 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-003 — Error display scenario #3
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
39 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-004 — Error display scenario #4
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
52 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-005 — Error display scenario #5
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
65 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-006 — Error display scenario #6
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
78 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-007 — Error display scenario #7
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
91 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-008 — Error display scenario #8
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
104 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-009 — Error display scenario #9
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
117 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-010 — Error display scenario #10
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
10 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-011 — Error display scenario #11
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
23 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-012 — Error display scenario #12
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
36 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-013 — Error display scenario #13
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
49 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-014 — Error display scenario #14
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
62 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-015 — Error display scenario #15
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
75 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-016 — Error display scenario #16
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
88 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-017 — Error display scenario #17
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
101 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-018 — Error display scenario #18
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
114 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-019 — Error display scenario #19
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
7 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-020 — Error display scenario #20
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
20 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-021 — Error display scenario #21
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
33 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-022 — Error display scenario #22
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
46 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-023 — Error display scenario #23
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
59 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-024 — Error display scenario #24
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
72 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-025 — Error display scenario #25
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
85 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-026 — Error display scenario #26
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
98 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-027 — Error display scenario #27
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
111 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-028 — Error display scenario #28
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
4 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-029 — Error display scenario #29
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
17 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-030 — Error display scenario #30
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
30 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-031 — Error display scenario #31
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
43 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-032 — Error display scenario #32
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
56 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-033 — Error display scenario #33
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
69 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-034 — Error display scenario #34
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
82 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-035 — Error display scenario #35
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
95 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-036 — Error display scenario #36
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
108 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-037 — Error display scenario #37
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
1 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-038 — Error display scenario #38
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
14 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-039 — Error display scenario #39
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
27 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-040 — Error display scenario #40
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
40 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-041 — Error display scenario #41
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
53 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-042 — Error display scenario #42
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
66 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-043 — Error display scenario #43
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
79 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-044 — Error display scenario #44
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
92 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-045 — Error display scenario #45
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
105 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-046 — Error display scenario #46
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
118 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-047 — Error display scenario #47
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
11 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-048 — Error display scenario #48
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
24 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-049 — Error display scenario #49
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
37 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-050 — Error display scenario #50
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
50 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-051 — Error display scenario #51
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
63 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-052 — Error display scenario #52
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
76 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-053 — Error display scenario #53
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
89 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-054 — Error display scenario #54
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
102 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-055 — Error display scenario #55
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
115 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-056 — Error display scenario #56
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
8 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-057 — Error display scenario #57
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
21 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-058 — Error display scenario #58
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
34 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-059 — Error display scenario #59
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
47 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-060 — Error display scenario #60
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
60 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-061 — Error display scenario #61
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
73 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-062 — Error display scenario #62
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
86 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-063 — Error display scenario #63
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
99 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-064 — Error display scenario #64
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
112 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-065 — Error display scenario #65
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
5 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-066 — Error display scenario #66
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
18 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-067 — Error display scenario #67
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
31 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-068 — Error display scenario #68
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
44 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-069 — Error display scenario #69
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
57 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-070 — Error display scenario #70
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
70 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-071 — Error display scenario #71
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
83 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-072 — Error display scenario #72
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
96 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-073 — Error display scenario #73
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
109 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-074 — Error display scenario #74
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
2 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-075 — Error display scenario #75
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
15 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-076 — Error display scenario #76
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
28 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-077 — Error display scenario #77
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
41 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-078 — Error display scenario #78
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
54 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-079 — Error display scenario #79
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
67 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-080 — Error display scenario #80
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
80 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-081 — Error display scenario #81
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
93 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-082 — Error display scenario #82
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
106 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-083 — Error display scenario #83
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
119 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-084 — Error display scenario #84
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
12 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-085 — Error display scenario #85
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
25 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-086 — Error display scenario #86
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
38 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-087 — Error display scenario #87
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
51 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-088 — Error display scenario #88
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
64 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-089 — Error display scenario #89
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
77 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-090 — Error display scenario #90
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
90 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-091 — Error display scenario #91
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
103 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-092 — Error display scenario #92
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
116 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-093 — Error display scenario #93
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
9 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-094 — Error display scenario #94
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
22 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-095 — Error display scenario #95
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
35 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-096 — Error display scenario #96
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
48 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-097 — Error display scenario #97
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
61 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-098 — Error display scenario #98
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
74 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-099 — Error display scenario #99
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
87 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-100 — Error display scenario #100
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
100 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-101 — Error display scenario #101
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
113 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-102 — Error display scenario #102
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
6 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-103 — Error display scenario #103
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
19 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-104 — Error display scenario #104
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
32 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-105 — Error display scenario #105
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
45 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-106 — Error display scenario #106
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
58 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-107 — Error display scenario #107
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
71 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-108 — Error display scenario #108
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
84 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-109 — Error display scenario #109
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
97 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-110 — Error display scenario #110
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
110 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-111 — Error display scenario #111
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
3 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-112 — Error display scenario #112
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
16 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-113 — Error display scenario #113
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
29 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-114 — Error display scenario #114
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
42 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-115 — Error display scenario #115
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
55 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-116 — Error display scenario #116
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
68 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-117 — Error display scenario #117
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
81 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-118 — Error display scenario #118
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
94 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-119 — Error display scenario #119
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
107 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-120 — Error display scenario #120
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
0 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-121 — Error display scenario #121
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
13 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-122 — Error display scenario #122
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
26 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-123 — Error display scenario #123
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
39 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-124 — Error display scenario #124
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
52 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-125 — Error display scenario #125
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
65 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-126 — Error display scenario #126
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
78 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-127 — Error display scenario #127
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
91 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-128 — Error display scenario #128
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
104 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-129 — Error display scenario #129
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
117 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-130 — Error display scenario #130
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
10 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-131 — Error display scenario #131
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
23 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-132 — Error display scenario #132
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
36 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-133 — Error display scenario #133
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
49 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-134 — Error display scenario #134
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
62 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-135 — Error display scenario #135
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
75 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-136 — Error display scenario #136
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
88 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-137 — Error display scenario #137
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
101 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-138 — Error display scenario #138
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
114 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-139 — Error display scenario #139
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
7 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-140 — Error display scenario #140
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
20 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-141 — Error display scenario #141
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
33 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-142 — Error display scenario #142
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
46 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-143 — Error display scenario #143
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
59 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-144 — Error display scenario #144
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
72 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-145 — Error display scenario #145
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
85 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-146 — Error display scenario #146
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
98 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-147 — Error display scenario #147
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
111 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-148 — Error display scenario #148
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
4 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-149 — Error display scenario #149
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
17 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-150 — Error display scenario #150
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
30 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-151 — Error display scenario #151
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
43 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-152 — Error display scenario #152
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
56 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-153 — Error display scenario #153
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
69 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Inline red text without text alternative for colorblind users (still fails a11y if only cue).
- Primary remediation: On invalid submit, focus first invalid field with
ref.focus()and scroll-margin. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-154 — Error display scenario #154
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
82 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Server returns 400 with unstructured body; UI cannot map to fields.
- Primary remediation: Disable native bubbles where custom validation is authoritative, intentionally.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-155 — Error display scenario #155
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
95 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Focus not moved to first error on submit in long forms.
- Primary remediation: Pair color with text + icon; ensure contrast meets guidelines.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-156 — Error display scenario #156
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
108 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Async validation error clears on blur unexpectedly due to competing effects.
- Primary remediation: Single owner of validation state per field: resolver OR manual, not both fighting.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-157 — Error display scenario #157
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
1 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Generic 'Invalid form' without
aria-liveregion for summary updates. - Primary remediation: Use RHF field array error paths
rootvs indexed keys consistently. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-158 — Error display scenario #158
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
14 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Double error: native constraint validation + custom errors both firing.
- Primary remediation: Normalize API errors to
{ field, message, code }[]at the client boundary. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.
ERR-159 — Error display scenario #159
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
27 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Field array errors keyed incorrectly after reorder.
- Primary remediation: Adopt stable error codes from API; map to fields with zod-like ergonomics.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Map server errors to fields explicitly—never guess by substring unless stable contract.
ERR-160 — Error display scenario #160
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
40 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Errors only shown as toast; screen reader users miss field association.
- Primary remediation: Use
role='alert'or polite live region for summary; keep inlinearia-describedby. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Accessible errors are part of the data model, not an afterthought CSS tweak.