Skip to content

errormessage

errormessage marks the element carrying a control’s validation message. Without it the message is red text near an input: assistive technology announces the invalid state but never reads why.

Status — React: Implemented • Web Components: Implemented • iOS: Not yet planned • Android: Not yet planned

The name comes from the ARIA attribute aria-errormessage. There is no ARIA role by this name, and the emitted wiring uses aria-describedby.

Roles

Apply the following roles to elements:

RoleTypeElement
errormessagePartElement of type: text or type: instance, or nested instance prop of type: string
descriptionPartElement of type: text or type: instance, or nested instance prop of type: string
WhereWhat is emitted
The message elementA generated id
The resolved controlaria-describedby referencing it, only while the message renders
An instance element carrying the roleRouting only — the wrapper’s tag never changes

description works identically for supplementary, non-error text.

Specs

Component anatomy typically has elements and roles like:

anatomy:
field:
type: container
role: textbox
errorText:
type: text
role: errormessage

Figma

Annotate the following layers:

  • the validation message layer as role:errormessage
  • supplementary help text as role:description

Place it beside a collapsing control, not inside it — content inside a collapse does not render.

React

Implementation

<TextInput label="Email" validation="invalid" errorText="Enter a valid email address." />

Before / After

// before
<div className="input" data-validation={p.validation} />
{p.validation === 'invalid' && (
<div className="error-text">{p.errorText}</div>
)}
// after
<input className="input" aria-invalid={invalid}
aria-describedby={invalid ? errorId : undefined} />
{invalid && (
<div className="error-text" id={errorId}>{p.errorText}</div>
)}

Contract

None. errormessage adds an id to its own element and an attribute to a different one. Validation state changes arrive through the control’s own contract — the invalid concept bridged to aria-invalid.

Web Components

Same emission within one shadow root. An id reference does not cross the boundary, so a message rendered by a different component cannot describe this control by id — the composed case recovers accessible text through partText() instead.

iOS

Not yet planned. Intended binding:

EmitsThe message folded into the field’s accessibility output
AnnouncedThe error is read together with the field

Android

Not yet planned. Intended binding:

EmitsModifier.semantics { error(message) } on the field
AnnouncedThe error is read together with the field

Additional details

Conditional by design

The message typically renders only while the invalid state is active, so the association appears and disappears with it. aria-describedby omits ids for elements whose render condition is false in the current variant — an aria-describedby pointing at an absent id is worse than none.

The role adds linkage, never show/hide logic. Visibility stays with the render condition the analysis already produced.

Roles never invent markup. Where no element carries the part, the control’s contract omits the message prop rather than shipping a dead one.

Resolution

SituationResult
Accepted by a value-bearing control or groupResolves to the component’s single value-bearing control, wherever either sits
Two elements claiming it for one controlError naming both
No candidate control in the componentValid — emits element and id, no wiring. Wiring arrives on composition

See also

  • label — the naming part; this is the describing part
  • textbox and checkbox — controls that accept it
  • States — the invalid concept that gates rendering
  • Roles overview — the vocabulary and how roles are authored