About This HTML Issue
Every element with role="cell" needs an ancestor with role="row", or a row that claims it through aria-owns.
An ARIA table nests its roles in a fixed order: table, then an optional rowgroup, then row, then cell (or columnheader and rowheader). Screen readers use that structure to announce a cell's row and column and to let people jump from cell to cell. A cell with no row above it has no position in the table, so a screen reader may read it as loose text or skip it during table navigation.
This usually happens when a table built from <div> elements has a wrapper for each row that carries a class for styling but never gets role="row". If that wrapper sits inside a role="rowgroup", the validator also reports that a child of the rowgroup must have role="row". Adding the missing role to the wrapper fixes both messages.
The row doesn't have to be the cell's direct parent. The validator accepts plain <div> or <span> wrappers between a role="row" element and its cells, so you can keep layout wrappers as long as some ancestor has the row role. When the cells can't sit inside the row in the DOM, give each cell an id and list those ids in aria-owns on the row.
Older validator versions word this message as an element with “role=row” instead of an element with the “role” value “row”, with the same cause and fix.
If the data is really tabular, a native <table> with <tr> and <td> gives you this structure without any role attributes.
Invalid example
Each plan wrapper groups two cells, but nothing marks it as a row.
<div role="table" aria-label="Subscription plans">
<div role="rowgroup">
<div class="plan">
<div role="cell">Basic</div>
<div role="cell">$10 per month</div>
</div>
<div class="plan">
<div role="cell">Pro</div>
<div role="cell">$25 per month</div>
</div>
</div>
</div>
Valid example
With role="row" on each wrapper, every cell has a row to belong to.
<div role="table" aria-label="Subscription plans">
<div role="rowgroup">
<div role="row" class="plan">
<div role="cell">Basic</div>
<div role="cell">$10 per month</div>
</div>
<div role="row" class="plan">
<div role="cell">Pro</div>
<div role="cell">$25 per month</div>
</div>
</div>
</div>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.