# axe-core aria-valid-attr-value error invalid value for aria-checked - how to fix it

## TL;DR

Set aria-checked to a valid value - true, false, or mixed, never yes, no, on, off, or 1 and 0. The same applies to every enumerated aria attribute, check the allowed values and fix the binding. One line of why: assistive tech only understands the spec's token list, anything else is treated as missing.

## The error, verbatim

```text
{
  "id": "aria-valid-attr-value",
  "impact": "critical",
  "help": "ARIA attributes must have valid values",
  "nodes": [
{"failureSummary":"Fix any of the following: Invalid ARIA attribute value: aria-checked="maybe"","target":[".toggle"]}
  ]
}
```

## Fix it step by step

### Step 1: Reproduce on one page

```bash
npx @axe-core/cli https://example.com --rules aria-valid-attr-value --save axe-val.json
```

Expected: Violations array contains aria-valid-attr-value with the bad value in each failure summary.

### Step 2: Extract the bad values

```bash
node -e "const r=require('./axe-val.json'); r.violations[0].nodes.forEach(function(n){console.log(n.target.join(' '), '-', n.failureSummary.match(/Invalid ARIA attribute value: ([^\n]+)/)[1])})"
```

Expected: Lists each attribute with its invalid value.

### Step 3: Find the bindings in source

```bash
rg -n 'aria-checked' src --glob '*.{jsx,tsx,vue}' | head -20
```

Expected: Shows the bindings producing the bad values, often a boolean rendered as a string.

### Step 4: Correct the values and re-scan

```bash
npx @axe-core/cli https://example.com --rules aria-valid-attr-value
```

Expected: Exit code 0, 0 violations. The toggle now announces checked and unchecked correctly.

### Step 5: Gate the rule in CI

```bash
npx @axe-core/cli https://example.com --exit | tail -3
```

Expected: Non-zero exit while any violation remains; add this command to CI so the fix never regresses.

## When to use this skill

- Your axe-core report lists this exact rule id under violations
- You are clearing automated WCAG 2.1 AA failures before a release or audit
- A CI a11y gate (pa11y-ci, lighthouse CI, cypress-axe) is red because of this rule

## When NOT to use this skill

- The issue only shows up in manual screen-reader testing and axe reports zero violations for the rule
- You are doing a full manual WCAG audit, this skill covers the single automated rule only
- The page is a third-party embed you cannot edit, flag it to the vendor instead

## Compatibility

axe-core 4.8+ (rule aria-valid-attr-value, WCAG 4.1.2). Same engine in axe DevTools and pa11y. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### invalid aria attribute value aria-checked

The failureSummary wording, same fix.

### axe aria attribute must have valid values

General phrasing covering all enumerated attributes like aria-sort or aria-current.

### axe DevTools flags the same rule

The browser extension runs the same rule engine; fix once and it clears in every runner.

## Why it happens

Framework bindings love rendering raw values into aria attributes: a JS boolean true becomes the string true (fine), but a custom state like maybe or a 1 and 0 pair does not map to the spec's token list. For aria-checked the only valid values are true, false, and mixed. Axe validates against the ARIA value types (true/false, tristate, token lists, ids), so anything outside the type fails even if it looks sensible to a human. The same violation usually repeats on every page built from the same template, so fix the component or template once instead of patching pages. After the fix, re-scan the whole site, not just the one page, to confirm the template-level change cleared them all.

## Edge cases

- In JSX, aria-checked={someBoolean} renders true and false correctly, the bug is usually a string like yes coming from state.
- mixed is only valid on checkbox and menuitemcheckbox, do not use it as a third state elsewhere.
- aria-hidden takes true, false, and the string undefined, the string false is fine, omitting the attribute is not the same.
- Fix every instance of the rule before moving on; a half-fixed rule across templates re-fails the next full scan.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_7xuDhsqjuad5ckoukyukBQ
