# pa11y timeout waiting for page load error - how to fix it

## TL;DR

Raise the timeout and wait for the right signal: pass --timeout and --wait to pa11y, and prefer waiting for network idle or a selector over a fixed sleep. If the page genuinely loads slowly, fix the page, not just the timeout. One line of why: pa11y scans whatever DOM exists when the timeout fires, so a too-short timeout scans a half-loaded page and reports garbage.

## The error, verbatim

```text
Error: Timeout waiting for page to load
    at pa11y (node_modules/pa11y/lib/pa11y.js)
    url: https://example.com/dashboard

```

## Fix it step by step

### Step 1: Reproduce with verbose logging

```bash
npx pa11y https://example.com/dashboard --timeout 30000 --reporter json | head -20
```

Expected: The timeout error repeats, confirming it is load timing, not a crash.

### Step 2: Time the real page load

```bash
curl -o /dev/null -s -w 'total: %{time_total}s\n' https://example.com/dashboard
```

Expected: Shows actual load time; if it exceeds the pa11y timeout, the timeout is simply too short.

### Step 3: Raise timeout and add a wait

```bash
npx pa11y https://example.com/dashboard --timeout 90000 --wait 2000 --reporter cli
```

Expected: Scan completes and reports violations instead of timing out.

### Step 4: Persist the settings

```bash
node -e "require('fs').writeFileSync('.pa11yci.json', JSON.stringify({timeout:90000,wait:2000},null,2))" && npx pa11y-ci --config .pa11yci.json | tail -5
```

Expected: The saved config makes the fix permanent for CI runs.

### 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

pa11y 6.x / pa11y-ci 3.x on Node 18+. The --timeout and --wait flags are the primary controls. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### pa11y error timeout waiting for page

Same error, same fix.

### pa11y scan hangs on slow page

Practitioner phrasing, often fixed by --wait for network idle instead of more timeout.

### 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

Pa11y defaults to a 30-second page load timeout, and dashboards with heavy client rendering or slow APIs exceed it. The timeout covers the initial load only, SPA hydration after load needs --wait. CI runners with throttled CPU make it worse: the page loads fine locally but times out in CI. Raising the timeout treats the symptom; if the page takes 60 seconds to load for real users, the scan timeout is telling you about a performance bug. 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

- --wait accepts milliseconds or a CSS selector, waiting for a selector like #app[data-ready] is more robust than a fixed sleep.
- Do not set the timeout to absurd values to mask a page that never finishes loading, find the hanging request instead.
- pa11y-ci runs pages in parallel, timeouts under parallel load differ from single runs, tune under CI conditions.
- 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_56H4bW3XT8u9y6Bo9oNz-g
