FA-8016 / Form validation / Open access
Validation message disclosure: An explicit empty error is treated as successful validation · case 01
An explicit empty error is treated as successful validation.
ROOT CAUSE
The empty message operation uses `if not error:` where the contract requires `if error is None:`.
VERIFIED REPAIR
Implement the empty message operation as `if error is None:`.
Unsuccessful approach: Truthiness in the opposite direction marks nonempty errors valid.
Case contract
Disabled fields hide errors; pending takes precedence; None alone means valid; errors become visible on touch or submit.
Why this case matters
A deterministic model of validation message disclosure; this isolates one interface invariant without requiring a browser.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(error, touched, submitted, disabled, pending):
if disabled: return 'hidden'
if pending: return 'checking'
if not error: return 'valid'
if touched or submitted: return error
return 'hidden'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve('required', True, True, True, False), 'hidden')
check('pending', solve('stale', True, True, False, True), 'checking')
check('empty error', solve('', True, False, False, False), '')
check('submit', solve('required', False, True, False, False), 'required')
check('touched', solve('required', True, False, False, False), 'required')
check('pristine', solve('required', False, False, False, False), 'hidden')
check('valid', solve(None, True, True, False, False), 'valid')
check('parameterized error', solve('error'+str(N), False, True, False, False), 'error'+str(N))
for repetition in range(N):
check('repeat valid', solve(None, True, True, False, False), 'valid')
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| disabled | hidden | hidden | Passed |
| pending | checking | checking | Passed |
| empty error | valid | | Failed |
| submit | required | required | Passed |
| touched | required | required | Passed |
| pristine | hidden | hidden | Passed |
| valid | valid | valid | Passed |
| parameterized error | error1 | error1 | Passed |
| repeat valid | valid | valid | Passed |
SHA-256 / c1cbeda8c9dd9751020e0e0325fa013010d2e8895558bcfb11420d65de760e07
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(error, touched, submitted, disabled, pending):
if disabled: return 'hidden'
if pending: return 'checking'
if error: return 'valid'
if touched or submitted: return error
return 'hidden'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve('required', True, True, True, False), 'hidden')
check('pending', solve('stale', True, True, False, True), 'checking')
check('empty error', solve('', True, False, False, False), '')
check('submit', solve('required', False, True, False, False), 'required')
check('touched', solve('required', True, False, False, False), 'required')
check('pristine', solve('required', False, False, False, False), 'hidden')
check('valid', solve(None, True, True, False, False), 'valid')
check('parameterized error', solve('error'+str(N), False, True, False, False), 'error'+str(N))
for repetition in range(N):
check('repeat valid', solve(None, True, True, False, False), 'valid')
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| disabled | hidden | hidden | Passed |
| pending | checking | checking | Passed |
| empty error | | | Passed |
| submit | valid | required | Failed |
| touched | valid | required | Failed |
| pristine | valid | hidden | Failed |
| valid | None | valid | Failed |
| parameterized error | valid | error1 | Failed |
| repeat valid | None | valid | Failed |
SHA-256 / b4fa1fa1f100e446eed1d7d6e251bfd8b2a87f10a2909354e4c38074f6a7b9ae
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(error, touched, submitted, disabled, pending):
if disabled: return 'hidden'
if pending: return 'checking'
if error is None: return 'valid'
if touched or submitted: return error
return 'hidden'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('disabled', solve('required', True, True, True, False), 'hidden')
check('pending', solve('stale', True, True, False, True), 'checking')
check('empty error', solve('', True, False, False, False), '')
check('submit', solve('required', False, True, False, False), 'required')
check('touched', solve('required', True, False, False, False), 'required')
check('pristine', solve('required', False, False, False, False), 'hidden')
check('valid', solve(None, True, True, False, False), 'valid')
check('parameterized error', solve('error'+str(N), False, True, False, False), 'error'+str(N))
for repetition in range(N):
check('repeat valid', solve(None, True, True, False, False), 'valid')
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| disabled | hidden | hidden | Passed |
| pending | checking | checking | Passed |
| empty error | | | Passed |
| submit | required | required | Passed |
| touched | required | required | Passed |
| pristine | hidden | hidden | Passed |
| valid | valid | valid | Passed |
| parameterized error | error1 | error1 | Passed |
| repeat valid | valid | valid | Passed |
SHA-256 / 6b97df8e4e85b74b3334a8680e9d6f6b2061ecd538af350f035faf38f60982e6
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:17.434501+00:00.
Case digest / 5aea2ac0ea425f5774a457871d54abe8db4242fd24c92a1f6a283503bf42b1c8