Identifies this entity as a pattern. Machine-readable identifier for the pattern (e.g., 'error-messaging', 'navigation', 'empty-state', 'form-validation'). MUST be unique within the documentation group.
Pattern: ^[a-z][a-z0-9-]*$
Human-readable name for display in docs (e.g., 'Error Messaging', 'Navigation', 'Empty State'). Modular metadata entries. Each entry is a typed object with a `kind` discriminator. Types include status, since, tags, category, aliases, summary, thumbnail, preview, extends, and links. All structured docs for this pattern as an ordered array of typed document block objects. Patterns accept pattern-specific document block types (interactions) and general types (guidelines, use-cases, accessibility, examples). Each document block entry has a `type` property that determines its shape. Ordering is significant: tools SHOULD preserve it for display. Interaction document block entries rely on ordering to represent chronological flow. Reference participating components through a links metadata entry (with type 'component', name, and role) rather than a dedicated document block type. Agent-optimized context for this pattern — intent, constraints, disambiguation, anti-patterns, examples, and keywords for efficient agentic consumption.
References: entityMetadata, patternDocumentBlock, agents, extensions { "kind": "pattern", "name": "error-messaging", "displayName": "Error Messaging", "metadata": [ { "kind": "description", "value": "Defines how errors are surfaced across the system — from inline field validation on forms to page-level error summaries and transient toast notifications. The pattern covers the lifecycle of an error from detection through resolution, ensuring that errors are perceivable, understandable, and actionable for all users including those relying on assistive technology." }, { "kind": "status", "status": "stable", "platformStatus": { "react": { "status": "stable", "since": "2.0.0" }, "web-component": { "status": "experimental", "since": "3.0.0", "description": "Partial implementation — inline validation works, error summary not yet available." }, "figma": { "status": "stable", "since": "2.0.0" } } }, { "kind": "since", "value": "2.0.0" }, { "kind": "tags", "items": [ "feedback", "validation", "forms", "errors", "accessibility" ] }, { "kind": "category", "value": "feedback" }, { "kind": "summary", "value": "A pattern for communicating errors through inline validation, summary banners, and toast notifications." }, { "kind": "links", "items": [ { "kind": "component", "name": "form-field", "role": "Container for individual inputs. Displays inline validation messages directly below the field when validation fails.", "required": true }, { "kind": "component", "name": "alert", "role": "Page-level error summary. Appears at the top of the form or page listing all current errors with anchor links to each invalid field.", "required": true }, { "kind": "component", "name": "toast", "role": "Transient notification for server-side or asynchronous errors that cannot be tied to a specific field (e.g., network failure, timeout)" }, { "kind": "component", "name": "icon", "role": "Visual error indicator displayed alongside inline validation text and inside the error summary. Provides a non-color signal that reinforces the error state.", "required": true }, { "kind": "component", "name": "button", "role": "Submit trigger for the form. Initiates client-side validation before submission.", "required": true }, { "kind": "component", "name": "link", "role": "Anchor links within the error summary that navigate the user to the corresponding invalid field.", "required": true }, { "kind": "design", "url": "https://design-tool.acme.com/file/abc123?node-id=3000:1", "label": "Design file — error messaging pattern" }, { "kind": "storybook", "url": "https://storybook.acme.com/?path=/docs/patterns-error-messaging--docs", "label": "Storybook pattern docs" }, { "kind": "documentation", "url": "https://design.acme.com/patterns/error-messaging", "label": "Documentation site" }, { "kind": "alternative", "url": "https://design.acme.com/patterns/success-messaging", "label": "success-messaging (pattern)" }, { "kind": "alternative", "url": "https://design.acme.com/patterns/notification-messaging", "label": "notification-messaging (pattern)" }, { "kind": "related", "url": "https://design.acme.com/patterns/empty-state", "label": "empty-state (pattern)" }, { "kind": "related", "url": "https://design.acme.com/components/form-field", "label": "form-field (component)" }, { "kind": "related", "url": "https://design.acme.com/components/alert", "label": "alert (component)" }, { "kind": "related", "url": "https://design.acme.com/components/toast", "label": "toast (component)" }, { "kind": "related", "url": "https://design.acme.com/tokens/color-text-error", "label": "color-text-error (token)" } ] } ], "documentBlocks": [ { "kind": "interactions", "items": [ { "trigger": "User submits the form by activating the submit button.", "description": "Client-side validation runs on all required fields. If one or more fields are invalid, submission is prevented and the error state is activated.", "components": [ "button", "form-field" ] }, { "trigger": "Client-side validation detects one or more invalid fields.", "description": "Each invalid field displays an inline error message directly below the input. The message describes what is wrong and, where possible, how to fix it. The field's border changes to the error color and an error icon appears to the left of the message text.", "components": [ "form-field", "icon" ], "examples": [ { "title": "Inline validation on a required email field", "presentation": { "kind": "image", "url": "https://design.acme.com/assets/patterns/error-inline-email.png", "alt": "An email input field with a red border. Below the field, a red error icon followed by the text 'Enter a valid email address' in the error text color." } }, { "title": "JSX — form field with error state", "presentation": { "kind": "code", "language": "jsx", "code": "<FormField\n label=\"Email address\"\n error=\"Enter a valid email address.\"\n required\n>\n <Input type=\"email\" value={email} onChange={setEmail} />\n</FormField>" } } ] }, { "trigger": "Two or more fields fail validation simultaneously.", "description": "An error summary alert appears at the top of the form. The summary lists every current error as an anchor link. Each link, when activated, moves focus to the corresponding invalid field. Focus is programmatically moved to the error summary so screen reader users are immediately aware of it.", "components": [ "alert", "link", "form-field" ], "examples": [ { "title": "Error summary banner with anchor links", "presentation": { "kind": "image", "url": "https://design.acme.com/assets/patterns/error-summary-banner.png", "alt": "A red-bordered alert at the top of a form titled 'There are 3 errors in this form'. Below the title are three bulleted links: 'Enter a valid email address', 'Password must be at least 8 characters', and 'Agree to the terms of service'. Each link text matches the inline error on the corresponding field." } } ] }, { "trigger": "User corrects an invalid field and moves focus away (blur) or types a valid value.", "description": "The inline error message for that field is removed. The field border returns to its default color. If an error summary is visible, the corresponding entry is removed from the summary. When all errors are resolved, the summary is removed entirely.", "components": [ "form-field", "alert" ] }, { "trigger": "Form submission succeeds on the client but fails on the server (e.g., 422, 500, network timeout).", "description": "A toast notification appears communicating the server error. The toast uses the error variant and includes a brief description of the problem and, if actionable, a retry button. If the server returns field-level validation errors (422), those are mapped back to inline field errors using the same pattern as client-side validation.", "components": [ "toast", "form-field", "button" ], "examples": [ { "title": "Toast for a network timeout", "presentation": { "kind": "image", "url": "https://design.acme.com/assets/patterns/error-toast-timeout.png", "alt": "A toast notification in the bottom-right corner of the screen with a red left border. The text reads 'Unable to save. Check your connection and try again.' A 'Retry' button appears to the right of the text." } } ] } ], "agents": { "intent": "Define the step-by-step flow for presenting error messages to the user.", "keywords": [ "flow", "steps", "validation", "error display", "recovery", "interaction" ] } }, { "kind": "purpose", "useCases": [ { "description": "When a user submits a form and one or more fields fail validation — whether client-side or server-side.", "kind": "positive" }, { "description": "When an asynchronous operation fails and the user needs to be informed (e.g., save failed, API error, network timeout).", "kind": "positive" }, { "description": "When the user needs to correct input before proceeding, such as during account creation, checkout, or settings changes.", "kind": "positive" }, { "description": "When the feedback is a successful outcome (e.g., 'Changes saved', 'Account created').", "kind": "negative", "alternative": { "name": "success-messaging", "rationale": "Success feedback uses the success color and icon. Reusing the error pattern for positive outcomes confuses the visual language and dilutes the urgency of actual errors." } }, { "description": "When the feedback is an informational or warning message that does not block the user from proceeding.", "kind": "negative", "alternative": { "name": "notification-messaging", "rationale": "Informational messages use a neutral or warning color. Treating them as errors creates false urgency and trains users to ignore error styling." } }, { "description": "When the entire page or view fails to load (e.g., 404, 503).", "kind": "negative", "alternative": { "name": "empty-state", "rationale": "Full-page failures are better handled by empty state patterns that replace the entire content area with an explanation and recovery action, rather than overlaying error messages on a non-functional page." } } ], "agents": { "intent": "Clarify when the error messaging pattern applies versus inline validation or toast notifications.", "disambiguation": [ { "entity": "toast notification", "distinction": "Error messaging is for persistent, actionable form errors; toasts are for transient, informational feedback." } ], "keywords": [ "when to use", "form errors", "validation", "feedback" ] } }, { "kind": "guideline", "items": [ { "guidance": "Always display inline errors directly below the invalid field, not in a separate location or only in the summary.", "rationale": "Users scan forms top-to-bottom. An error placed away from its field forces the user to map the message to the field mentally. Proximity eliminates that cognitive load.", "kind": "required", "category": "visual-design" }, { "guidance": "Error messages must describe the problem and, when possible, suggest how to fix it.", "rationale": "A message like 'Invalid input' forces the user to guess what went wrong. A message like 'Enter a date in MM/DD/YYYY format' removes ambiguity and speeds correction.", "kind": "required", "category": "content" }, { "guidance": "When two or more fields have errors, display an error summary at the top of the form in addition to inline messages.", "rationale": "Users on long forms may not see all inline errors, especially those below the fold. The summary provides a single scannable list of everything that needs attention.", "kind": "required", "category": "visual-design" }, { "guidance": "Each entry in the error summary must link to the corresponding invalid field.", "rationale": "Keyboard and screen reader users need a way to navigate directly from the summary to the problematic field without tabbing through the entire form.", "kind": "required", "category": "interaction" }, { "guidance": "Move focus to the error summary when it appears.", "rationale": "Screen reader users will not discover the summary unless focus is moved to it. Sighted keyboard users benefit from the same behavior — their next Tab press lands them in the summary's link list.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#error-identification" } ] }, { "guidance": "Do not clear the form or reset field values when validation fails.", "rationale": "Clearing the form destroys the user's work. They must re-enter all data, including fields that were valid. This is hostile to all users and catastrophic for users with motor impairments who rely on slow, deliberate input.", "kind": "prohibited", "category": "interaction" }, { "guidance": "Use real-time inline validation only for fields where the constraint is unambiguous and immediate feedback is helpful (e.g., password strength, email format). Do not validate on every keystroke for fields that require the user to finish typing.", "rationale": "Premature validation interrupts the user. Showing 'Invalid email' while the user is still typing 'j' is noise. Wait for a blur event or a pause in typing.", "kind": "encouraged", "category": "interaction" }, { "guidance": "Pair every inline error message with an error icon. Do not rely on color alone.", "rationale": "Approximately 8% of men have some form of color vision deficiency. An icon provides a second, non-color signal that the field is in an error state. WCAG 1.4.1 requires that color is not the sole means of conveying information.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#use-of-color" } ] }, { "guidance": "Each inline error message must be programmatically associated with its field using aria-describedby.", "rationale": "Screen readers announce aria-describedby content when the field receives focus. Without it, the user hears the field label but not the error, and has no way to know the field is invalid.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#error-identification" }, { "url": "https://www.w3.org/TR/WCAG22/#info-and-relationships" } ] }, { "guidance": "Invalid fields must be marked with aria-invalid=\"true\".", "rationale": "The aria-invalid attribute allows screen readers to announce that a field's value is not accepted. It is the standard mechanism for communicating validation state in ARIA.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#error-identification" } ] }, { "guidance": "The error summary must use role=\"alert\" or be injected into an aria-live=\"assertive\" region so that screen readers announce it immediately when it appears.", "rationale": "Without a live region, screen readers will not announce dynamically injected content. The user will not know the summary exists unless they navigate to it manually.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#status-messages" } ] }, { "guidance": "Error summary anchor links must move focus to the corresponding field, not just scroll to it.", "rationale": "Keyboard users rely on focus position to interact. Scrolling without moving focus leaves the keyboard cursor at the summary, requiring the user to Tab through potentially many elements to reach the field.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#focus-order" } ] }, { "guidance": "Toast notifications for errors must persist until the user dismisses them or the error is resolved. Do not auto-dismiss error toasts.", "rationale": "Users with cognitive disabilities or screen reader users may need more time to read and understand the error. Auto-dismissing the toast removes the information before they can act on it.", "kind": "required", "category": "accessibility", "criteria": [ { "url": "https://www.w3.org/TR/WCAG22/#timing-adjustable" } ] } ], "agents": { "intent": "Enforce correct error message presentation and content rules.", "constraints": [ { "rule": "Error messages must describe what went wrong and how to fix it.", "level": "must" }, { "rule": "Do not use color alone to indicate an error state.", "level": "must-not" } ], "keywords": [ "rules", "content", "error text", "visual design" ] } }, { "kind": "accessibility", "wcagLevel": "AA", "keyboardInteraction": [ { "key": "Tab", "action": "Moves focus to the next focusable element. When the error summary is visible, focus moves into the summary's link list." }, { "key": "Enter", "action": "Activates a link in the error summary, moving focus to the corresponding invalid field." }, { "key": "Escape", "action": "Dismisses the toast notification, if one is visible." } ], "screenReaderBehavior": "When validation fails, the error summary is announced immediately via aria-live='assertive'. Each summary link is announced as 'link, [error text]'. When an invalid field receives focus, the screen reader announces '[label], edit text, invalid entry, [error message]'.", "focusManagement": "On validation failure, focus moves to the error summary. Activating a summary link moves focus to the corresponding field. When a field error is resolved, focus remains on the field. When all errors are resolved and the summary is removed, focus is not moved — the user continues from their current position.", "agents": { "intent": "Provide ARIA and keyboard requirements for accessible error messaging.", "keywords": [ "WCAG", "aria-live", "focus management", "screen reader", "a11y" ] } } ], "agents": { "intent": "Guide multi-component composition for surfacing, communicating, and resolving form validation errors.", "constraints": [ { "rule": "Always include both an inline field error and a summary when multiple fields fail.", "level": "must" }, { "rule": "Do not use toast notifications as the sole error communication for form validation.", "level": "must-not" } ], "disambiguation": [ { "entity": "empty-state", "distinction": "Use error-messaging for validation and system errors; use empty-state for the absence of content." }, { "entity": "alert", "distinction": "Use error-messaging for form validation flows; use alert for non-form system or status messages." } ], "antiPatterns": [ { "description": "Showing errors only on submit without inline field feedback.", "instead": "Show inline errors on field blur and in a summary on submit." } ], "keywords": [ "error", "validation", "form", "feedback", "inline-error", "error-summary", "alert" ] }, "$extensions": { "com.designTool": { "patternId": "pattern-error-messaging-001" } } }

Design System Documentation Standard (DSDS) 0.1 — Draft Specification

GitHub