---
title: "Check fields when people leave them · Agent Wranglers"
url: https://agentwranglers.se/playbook/app-ui/forms/validation-timing
updated: 2026-10-20
licence: "All rights reserved"
---

# Check fields when people leave them

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [Forms](https://agentwranglers.se/playbook/app-ui/forms)
- Rule: Check a field first when focus leaves it, then on every change once it shows an error, and check all fields on submit. Never show an error on a field nobody has touched.
- How: Track whether each field has been left once. Before that, stay silent while people type. After an error appears, check on every input, so the message goes away as soon as the value is fixed. On submit, check every field, then follow [form errors](https://agentwranglers.se/playbook/website/accessibility/form-errors) for the messages and focus. Labels follow [form labels](https://agentwranglers.se/playbook/website/accessibility/form-labels).
- Check: A browser test types one letter into the email field. No error shows. It tabs away, and the error shows. It fixes the value, and the error goes away before focus leaves.

Example:

```ts
export function watchField(input: HTMLInputElement, validate: (value: string) => string | null, showError: (message: string | null) => void) {
  let isTouched = false;
  const run = () => showError(validate(input.value));
  input.addEventListener('blur', () => { isTouched = true; run(); });
  input.addEventListener('input', () => { if (isTouched && input.getAttribute('aria-invalid') === 'true') run(); });
}
```

```python
from playwright.sync_api import expect

def test_email_error_waits_for_blur(page):
    page.goto("https://staging.example.com/signup")
    email = page.get_by_label("Email")
    email.fill("a")
    expect(email).not_to_have_attribute("aria-invalid", "true")
    email.blur()
    expect(email).to_have_attribute("aria-invalid", "true")
    email.fill("ada@example.com")
    expect(email).not_to_have_attribute("aria-invalid", "true")
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/forms/validation-timing`.

- Next: [Check every field on the server too](https://agentwranglers.se/playbook/app-ui/forms/server-side-validation)
- [Forms](https://agentwranglers.se/playbook/app-ui/forms)
