A reviewer found three wrong WCAG criteria in my accessibility plugin. I went looking, and found eight.

I build a WordPress accessibility scanner. Last week a marketplace reviewer rejected it, and among the reasons was this:

The compliance rules need correction. "Language of parts" only validates existing lang attributes and cannot detect unmarked foreign-language passages; the main-landmark rule is WCAG 1.3.6 Level AAA but is marketed as an AA check; and duplicate IDs should not be presented as a WCAG 2.2 failure under 4.1.1.

Three findings. All three correct. What follows is what happened when I stopped fixing the three and checked the other twenty-two.

The rule that no longer exists

Start with the third one, because it is the easiest to verify and the most widely wrong.

Success criterion 4.1.1 Parsing was removed from WCAG 2.2. Not deprecated, not softened — removed. The W3C Recommendation lists it in the conformance section as "Parsing (Obsolete and removed)". It went because the thing it protected against — assistive technology choking on malformed markup — stopped being a real failure mode once browsers and accessibility APIs converged on how to recover from bad HTML.

My scanner reported duplicate id attributes as a WCAG 4.1.1 failure. Against WCAG 2.2, that criterion is not there to fail.

Duplicate ids are still worth fixing. They break label for pairings and aria-labelledby references, so the wrong element gets announced, or none does. But that is a 4.1.2 problem when it actually breaks an accessible name, and detecting that is a different check from counting duplicate ids. What I had was a generic duplicate-id check wearing a criterion number that had been retired.

Then I checked the rest

The reviewer had found three. I could have fixed three. Instead I took all 25 rules and checked each one against the WCAG 2.2 Recommendation and against how axe-core classifies the equivalent rule — because axe-core is the reference implementation most of this industry is built on, and it makes a distinction I had lost.

Eight rules were wrong.

Rule Claimed Actually
Duplicate ids 4.1.1 Removed from WCAG 2.2
One main landmark 1.3.6 AAA 1.3.6 is Identify Purpose, an unrelated criterion
Language of parts 3.1.2 AA 3.1.2 is level A — and the check does not do what its title claimed
Vague link text 2.4.4 2.4.4 is satisfiable from surrounding context
Skipped heading levels 1.3.1 WCAG does not require sequential heading levels
Missing h1 1.3.1 Recommended practice
Empty heading 1.3.1 Recommended practice
Positive tabindex 2.4.3 Recommended practice

Some of those deserve a sentence.

Vague link text. 2.4.4 is Link Purpose (In Context). In context. A link that says "read more" satisfies it if the surrounding paragraph, list item or table cell makes the destination clear — which is usually the case. The criterion that demands the link text stand alone is 2.4.9, and it is AAA. So "read more" repeated down a page is a real usability problem for someone tabbing through links, and it is not a level A failure.

Heading levels. There is no success criterion requiring h2 to follow h1. 1.3.1 Info and Relationships requires that structure conveyed visually is available programmatically — using headings at all is how you satisfy it. Skipping from h1 to h3 is untidy and it makes screen reader navigation worse, but it is not what 1.3.1 says. axe-core classifies heading-order as best practice, and has for years.

Language of parts. This one was wrong twice. 3.1.2 is level A, not AA — I had the level wrong. And the check was titled "Foreign-language passages should declare their language", which promised something no automated check can do: to know that a passage is in another language when nothing marks it as such. What the code actually did was validate lang attributes that were already present. That is a useful check. It is not the check the title advertised.

So what are the real numbers

25 checks. Eighteen map to a WCAG 2.2 success criterion, across fourteen distinct criteria at levels A and AA: 1.1.1, 1.3.1, 1.3.5, 1.4.2, 1.4.3, 1.4.4, 2.4.1, 2.4.2, 2.4.4, 2.5.8, 3.1.1, 3.1.2, 3.3.2 and 4.1.2.

Seven are recommended practice. Worth fixing, not conformance failures.

Before the audit, the product page said "25 automated checks across WCAG 2.2 levels A and AA" and listed 4.1.1 among the criteria covered. Both of those were false, and the second was checkably false by anyone who had read the 2.2 Recommendation.

Why this is not pedantry

Here is the part that made me stop treating it as a labelling problem.

The plugin has a generator for the accessibility information the European Accessibility Act requires. It prefills the "known barriers" section from your most recent scan, and — this was the selling point — it attaches the WCAG success criterion to each barrier.

So eight rules citing criteria that were wrong, obsolete, or unrelated were writing those numbers into a document the site owner publishes as a legal declaration about their own service.

A conformance claim is not a report. A report that overstates gives you a worse afternoon. A published statement that cites a criterion that does not exist, on a document you are legally obliged to maintain, is a different category of mistake, and it is one your customer discovers rather than you.

That is the argument for the distinction, and it is the only one that matters. A tool that presents every finding as a WCAG failure inflates two numbers: its own — 25 WCAG checks reads better than 18 — and yours. And your inflated number is the one that ends up in public.

What I changed

Every rule now declares what it is:

{
    id: 'heading_order',
    wcag: '',
    level: '',
    standard: 'best-practice',
    ...
}

The report prints the criterion where there is one, and Best practice where there is not, instead of an empty WCAG ().

The statement generator now requires two independent conditions before it will print a criterion into a legal document: the rule must be marked as WCAG-mapped, and its value must match ^\d+\.\d+\.\d+$. Either one alone would have been enough to stop what happened. I wanted the one that survives someone editing the other.

And the marketing copy now says 18 and 7, in the readme, the documentation and the marketplace listing. That was the least pleasant commit of the week and the one I would repeat.

If you build or buy one of these tools

Three questions worth asking, none of which require you to trust me.

Does it still report 4.1.1? Thirty seconds to check, and it tells you when the rule set was last read against the standard rather than copied from another tool.

Does it distinguish success criteria from good practice? If every finding carries a criterion number, at least some of those numbers are decoration. The reference implementation this industry runs on marks roughly a quarter of its rules as best practice. A tool with none is not stricter; it is less careful.

Where does the criterion go after the report? If it flows into a statement, a badge, a PDF, or anything a customer publishes, the accuracy stops being an internal quality matter.

The part that has not changed

Automated testing finds roughly a third of real accessibility barriers. Getting the labels right does not move that number. A clean report is a good sign, not a conformance statement, and keyboard and screen reader testing by a person is still the only way to know.

What the audit changed is narrower and, I think, worth the week: when my tool now says WCAG, it means it.