Skip to content

fix(a11y-critical): log unknown ids in options.rules, do not throw - #293

Draft
Aaryan430 wants to merge 2 commits into
mainfrom
fix/options-rules-unknown-id
Draft

fix(a11y-critical): log unknown ids in options.rules, do not throw#293
Aaryan430 wants to merge 2 commits into
mainfrom
fix/options-rules-unknown-id

Conversation

@Aaryan430

Copy link
Copy Markdown
Collaborator

options.rules is an enable/disable map. An id in it that the current axe
instance does not know is a no-op — both consumers of the map
(get-check-option.js, rule-should-run.js) look ids up by key and never
enumerate it, so an extra key cannot change how any rule runs.

Validation nevertheless threw on such an id, which turns a harmless extra key
into a rejected axe.run. In a multi-frame run that is fatal: a frame whose
rule registry differs from the caller's rejects, and
collect-results-from-frames propagates one frame's error as a rejection of
the whole run, so the entire result set is lost.

This makes an unknown id in options.rules log and continue, matching what
normalizeRunOptions already does ten lines above for an unmatched tag in
options.runOnly.

options.runOnly is unchanged and still throws — it means "run only these",
so an unknown id there means the caller gets nothing they asked for and
silence would be wrong.

Tests: replaces the throw assertion with three specs — the unknown id is
logged, no error is raised, and known ids in the same map are still applied.

Aaryan430 and others added 2 commits August 21, 2026 10:03
options.rules is an enable/disable map and its consumers look ids up by
key, so an id the current instance does not know is a no-op. Throwing on
one turns a harmless extra key into a rejected axe.run, and in a
multi-frame run a single frame's rejection discards the whole result set.

Log and continue instead, matching the existing behaviour for an
unmatched tag in options.runOnly. options.runOnly still throws on an
unknown rule id.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…it is replaced

configure() reports success by not throwing and returns nothing, and
_load() replaces axe._audit outright — so a caller cannot tell a
completed registration from one that was later discarded. The built
axe.js calls _load on evaluation, which makes a second evaluation in one
context reset the registry to stock with no error raised.

Record the before/after rule counts on audit.lastConfigure, carry a
generation counter across _load, and log when _load replaces an existing
audit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant