FAILURE MAP
← Case archive

FA-11421 / Accessibility interaction semantics / Open access

Error text replaces persistent instructions in the description channel · case 01

Invalid controls lose their usage hint, or error text remains announced after validation succeeds.

Verified by executionVariant 1 · 6 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The description is treated as a single interchangeable hint-or-error slot.

VERIFIED REPAIR

Keep instructions and add error text only while invalid; never modify the control name.

Unsuccessful approach: Always appending error text keeps stale errors after invalid state clears.

Case contract

Given a name, hint, error text and invalid boolean, return [name,description]. Description joins nonempty hint and (only when invalid) error with one space. Name is preserved verbatim. This models channel assembly, not reference resolution or validation timing.

Why this case matters

A controlled offline accessibility-data model. It isolates the stated contract; it does not simulate browser accessibility APIs or claim full ARIA conformance.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(name, hint, error, invalid):
    return [name, error if invalid else hint]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hint remains with error', solve('Field '+str(N), 'Use digits', 'Required', True), ['Field '+str(N),'Use digits Required'])
check('valid suppresses stale error', solve(str(N), 'Use digits', 'Required', False), [str(N),'Use digits'])
check('no hint', solve(str(N), '', 'Required', True), [str(N),'Required'])
check('empty error retains hint', solve(str(N), 'Use digits', '', True), [str(N),'Use digits'])
check('empty channels', solve(str(N), '', '', False), [str(N),''])
check('name never replaced', solve('Name '+str(N), '', 'Error', False), ['Name '+str(N),''])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
hint remains with error['Field 1', 'Required']['Field 1', 'Use digits Required']Failed
valid suppresses stale error['1', 'Use digits']['1', 'Use digits']Passed
no hint['1', 'Required']['1', 'Required']Passed
empty error retains hint['1', '']['1', 'Use digits']Failed
empty channels['1', '']['1', '']Passed
name never replaced['Name 1', '']['Name 1', '']Passed

SHA-256 / dcd00ea3251c93eb138667014bc4089443f8e087219c17529d5f24f65ed8dabc

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(name, hint, error, invalid):
    return [name, ' '.join(part for part in [hint,error] if part)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hint remains with error', solve('Field '+str(N), 'Use digits', 'Required', True), ['Field '+str(N),'Use digits Required'])
check('valid suppresses stale error', solve(str(N), 'Use digits', 'Required', False), [str(N),'Use digits'])
check('no hint', solve(str(N), '', 'Required', True), [str(N),'Required'])
check('empty error retains hint', solve(str(N), 'Use digits', '', True), [str(N),'Use digits'])
check('empty channels', solve(str(N), '', '', False), [str(N),''])
check('name never replaced', solve('Name '+str(N), '', 'Error', False), ['Name '+str(N),''])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
hint remains with error['Field 1', 'Use digits Required']['Field 1', 'Use digits Required']Passed
valid suppresses stale error['1', 'Use digits Required']['1', 'Use digits']Failed
no hint['1', 'Required']['1', 'Required']Passed
empty error retains hint['1', 'Use digits']['1', 'Use digits']Passed
empty channels['1', '']['1', '']Passed
name never replaced['Name 1', 'Error']['Name 1', '']Failed

SHA-256 / 12a374fff565c192790e2bd1c3fd5689b7d2d40585ee0ab1d46806930d82a31b

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(name, hint, error, invalid):
    return [name, ' '.join(part for part in [hint, error if invalid else ''] if part)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('hint remains with error', solve('Field '+str(N), 'Use digits', 'Required', True), ['Field '+str(N),'Use digits Required'])
check('valid suppresses stale error', solve(str(N), 'Use digits', 'Required', False), [str(N),'Use digits'])
check('no hint', solve(str(N), '', 'Required', True), [str(N),'Required'])
check('empty error retains hint', solve(str(N), 'Use digits', '', True), [str(N),'Use digits'])
check('empty channels', solve(str(N), '', '', False), [str(N),''])
check('name never replaced', solve('Name '+str(N), '', 'Error', False), ['Name '+str(N),''])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
hint remains with error['Field 1', 'Use digits Required']['Field 1', 'Use digits Required']Passed
valid suppresses stale error['1', 'Use digits']['1', 'Use digits']Passed
no hint['1', 'Required']['1', 'Required']Passed
empty error retains hint['1', 'Use digits']['1', 'Use digits']Passed
empty channels['1', '']['1', '']Passed
name never replaced['Name 1', '']['Name 1', '']Passed

SHA-256 / df3aca93a87b0751c12dd65b5a96e56153367aae2428ef6b86f34a5879070d47

Verification & scope

This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:38:47.818929+00:00.

Case digest / 471c3dc343b650dbae1408b9cbbde35b28116aba5ab4e9bcc7d7c879e8380a01