# lighthouse ci failed assertion on accessibility category - how to fix it

## TL;DR

Read which assert failed in the LHCI output, fix the underlying audits, and keep assertions as the quality contract. LHCI assert fails the build when any configured assertion trips, and the accessibility category assertion is usually a minScore. One line of why: the assertion is a promise about quality, and the fix is keeping the promise, not deleting it.

## The error, verbatim

```text
Error: Failed on assertion: accessibility category minScore 0.9, actual 0.84
    at lhci assert (node_modules/@lhci/cli/src/assert.js)

```

## Fix it step by step

### Step 1: Reproduce the assertion

```bash
npx lhci assert | rg -i 'fail|assertion' | head -10
```

Expected: The same assertion failure reproduces.

### Step 2: See the failing audits

```bash
npx lighthouse https://example.com/ --only-categories=accessibility --output=json --output-path=lh.json | tail -2 && node -e "const r=require('./lh.json'); Object.entries(r.audits).forEach(function([k,v]){if(v.score!==null&&v.score!==1)console.log(k,v.score)})"
```

Expected: Lists the audits dragging the category score down.

### Step 3: Fix the audits

```bash
node -e "console.log('apply the rule-specific fixes for each failing audit')"
```

Expected: Work through the failing audits heaviest first.

### Step 4: Re-run assert

```bash
npx lhci assert | tail -4
```

Expected: Assertions pass and the build goes green.

### Step 5: Re-run twice to rule out flakes

```bash
npx pa11y https://example.com/ | tail -2
```

Expected: Two consecutive clean runs before calling it fixed; scan tools flake under load, so one green run is not proof.

## When to use this skill

- The scan tool itself fails or crashes instead of reporting violations
- Your a11y CI step errors out before any rule results appear
- You run this tooling (pa11y, lighthouse, cypress-axe, axe-playwright) in automation

## When NOT to use this skill

- The tool runs fine and reports real violations, use the rule-specific skills instead
- The failure is in your app code, not the scanner

## Compatibility

LHCI (lighthouse-ci) with lighthouserc assert config. Assertions support minScore, maxLength, and audit-level checks. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### lhci assert accessibility failed

Same failure, same fix.

### lighthouse-ci assertion error a11y

Practitioner phrasing.

### same failure locally and in CI

Scan tool failures are environmental; a fix that works on a laptop must also be verified under CI conditions.

## Why it happens

LHCI assert compares Lighthouse results against configured assertions, commonly a minimum accessibility category score. The score drops when new violations ship, so the assertion failure is a regression signal. Teams sometimes respond by deleting the assertion, which trades a red build for silent decay. The assertion config (which audits, what scores) is the quality contract, and the fix is meeting it. Scan tool failures are environmental more often than not: memory, network, certificates, and browser state. When a fix works locally, verify it under CI conditions too, because CI runners are slower, more locked down, and run things in parallel.

## Edge cases

- Audit-level assertions (single audit must pass) are stricter and more stable than category minScore.
- LHCI supports warn vs error assertion levels, use warn for new assertions while the team fixes up.
- Median of multiple runs beats a single run for assertion stability on dynamic pages.
- Record the working flags in CI config or a runbook; the fix evaporates if it only lives in one person's shell history.

## Provenance

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