# Form validation error messages associated with fields and describe how to fix the error

- **Pattern:** `ab-001601` (`gov-section-508.keyboard-assistive.error-messages`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001601
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001601)

## Why it matters

When form validation fails, screen reader users must know three things: that an error occurred, which field is affected, and how to correct it. Displaying a red border or showing text only visually is invisible to AT. Without `aria-invalid` and `aria-describedby` wiring the error message to the input, screen reader users hear only the field name repeated—no indication that anything is wrong. WCAG 2.2 SC 3.3.1 (Level A) requires errors to be identified in text, and SC 3.3.3 (Level AA) requires suggestions for correction. Section 508 2018 Refresh 502.3.6 covers form field associations. Every form submission failure that goes unannounced to screen reader users silently breaks a user journey.

## Severity rationale

Medium because inaccessible error messages impair form completion for screen reader users but do not prevent them from eventually reaching the correct field through sequential navigation.

## Remediation

Wire error messages to their inputs using `aria-invalid` and `aria-describedby`, and use `role="alert"` or `aria-live="polite"` to announce errors on insertion. In your form components:
```tsx
const [emailError, setEmailError] = useState('');

<div>
  <label htmlFor="email">Email address</label>
  <input
    id="email"
    type="email"
    aria-invalid={emailError ? 'true' : 'false'}
    aria-describedby={emailError ? 'email-error' : undefined}
  />
  {emailError && (
    <div id="email-error" role="alert" className="error-text">
      {emailError}
    </div>
  )}
</div>
```
Error messages must be actionable—"Email must contain an @ symbol" not "Invalid email". Set focus to the first errored field after submission to orient keyboard users.

## Detection

- **ID:** `error-messages`
- **Severity:** `medium`
- **What to look for:** Count all relevant instances and enumerate each. Check all form inputs for validation. When a form field has an error, verify that: (1) the error message is visually associated with the field, (2) the error message is announced to screen readers via `aria-describedby` or `aria-invalid`, (3) the error message explains what's wrong and how to fix it (not just "Invalid input").
- **Pass criteria:** Every form input with an error has an associated error message visible both visually and to screen readers. At least 1 implementation must be verified. Error messages are descriptive (e.g., "Email must contain @ symbol" not just "Invalid").
- **Fail criteria:** Error messages are displayed only visually (no ARIA association), or error messages are generic and unhelpful.
- **Skip (N/A) when:** No form validation exists.
- **Detail on fail:** Example: `"Email validation error displays red text 'Invalid email' below the field but does not use aria-describedby to announce it to screen readers. Password field shows 'Password must be 8+ characters' but only as a red outline, with no associated error message element."`
- **Remediation:** Associate error messages with form fields:
  ```tsx
  const [emailError, setEmailError] = useState('');

  <input
    id="email"
    type="email"
    aria-invalid={emailError ? 'true' : 'false'}
    aria-describedby={emailError ? 'email-error' : undefined}
  />
  {emailError && <div id="email-error" role="alert">{emailError}</div>}
  ```
  Use `role="alert"` or `aria-live="polite"` to announce errors when they appear:
  ```tsx
  <div id="email-error" role="alert" aria-live="polite">
    Email must contain an @ symbol
  </div>
  ```

- **Cross-reference:** For related patterns and deeper analysis, see the corresponding checks in other AuditBuffet audits covering this domain.

---

## External references

- wcag 3.3.1
- wcag 3.3.3
- section-508 502.3.6

Taxons: accessibility

HTML version: https://auditbuffet.com/patterns/ab-001601
