FAILURE MAP
← Case archive

FA-8606 / Client navigation / Open access

Pagination button state: Empty results display a nonexistent first page · case 01

Empty results display a nonexistent first page.

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

ROOT CAUSE

The empty operation uses `if pages == 0: return (1, False, False)` where the contract requires `if pages == 0: return (0, False, False)`.

VERIFIED REPAIR

Implement the empty operation as `if pages == 0: return (0, False, False)`.

Unsuccessful approach: Enabling navigation on empty results offers unusable controls.

Case contract

Empty pagination uses page zero with disabled controls; nonempty page clamps to 1..pages; actions move by one or to endpoints; availability reflects resulting page.

Why this case matters

A deterministic model of pagination button state; 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(page, pages, action):
    if pages == 0: return (1, False, False)
    page = max(1, min(page, pages))
    if action == 'first': page = 1
    elif action == 'last': page = pages
    elif action == 'next': page = min(pages, page+1)
    elif action == 'previous': page = max(1, page-1)
    return (page, page > 1, page < pages)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('empty', solve(1, 0, "none"), (0, False, False))
check('shrink', solve(8, 3, "none"), (3, True, False))
check('zero', solve(0, 3, "none"), (1, False, True))
check('last', solve(1, 5, "last"), (5, True, False))
check('next end', solve(5, 5, "next"), (5, True, False))
check('next step', solve(1, 5, "next"), (2, True, True))
check('previous start', solve(1, 5, "previous"), (1, False, True))
check('previous step', solve(4, 5, "previous"), (3, True, True))
check('parameterized page count', solve(N,N+1,'next'), (N+1,True,False))
for repetition in range(N):
    check('repeat previous step', solve(4, 5, "previous"), (3, True, True))
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
empty[1, False, False][0, False, False]Failed
shrink[3, True, False][3, True, False]Passed
zero[1, False, True][1, False, True]Passed
last[5, True, False][5, True, False]Passed
next end[5, True, False][5, True, False]Passed
next step[2, True, True][2, True, True]Passed
previous start[1, False, True][1, False, True]Passed
previous step[3, True, True][3, True, True]Passed
parameterized page count[2, True, False][2, True, False]Passed
repeat previous step[3, True, True][3, True, True]Passed

SHA-256 / de8d9c1926dcc401b522c22a6867de6e4ab3ae552f76857ebed7bee3b0f76560

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(page, pages, action):
    if pages == 0: return (0, True, True)
    page = max(1, min(page, pages))
    if action == 'first': page = 1
    elif action == 'last': page = pages
    elif action == 'next': page = min(pages, page+1)
    elif action == 'previous': page = max(1, page-1)
    return (page, page > 1, page < pages)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('empty', solve(1, 0, "none"), (0, False, False))
check('shrink', solve(8, 3, "none"), (3, True, False))
check('zero', solve(0, 3, "none"), (1, False, True))
check('last', solve(1, 5, "last"), (5, True, False))
check('next end', solve(5, 5, "next"), (5, True, False))
check('next step', solve(1, 5, "next"), (2, True, True))
check('previous start', solve(1, 5, "previous"), (1, False, True))
check('previous step', solve(4, 5, "previous"), (3, True, True))
check('parameterized page count', solve(N,N+1,'next'), (N+1,True,False))
for repetition in range(N):
    check('repeat previous step', solve(4, 5, "previous"), (3, True, True))
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
empty[0, True, True][0, False, False]Failed
shrink[3, True, False][3, True, False]Passed
zero[1, False, True][1, False, True]Passed
last[5, True, False][5, True, False]Passed
next end[5, True, False][5, True, False]Passed
next step[2, True, True][2, True, True]Passed
previous start[1, False, True][1, False, True]Passed
previous step[3, True, True][3, True, True]Passed
parameterized page count[2, True, False][2, True, False]Passed
repeat previous step[3, True, True][3, True, True]Passed

SHA-256 / 08e1804b2847b3b22f7336eec4ae5970ae153375d33574ae1770a012ef68b980

3 / The verified repair

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

N = 1
observations = []
def solve(page, pages, action):
    if pages == 0: return (0, False, False)
    page = max(1, min(page, pages))
    if action == 'first': page = 1
    elif action == 'last': page = pages
    elif action == 'next': page = min(pages, page+1)
    elif action == 'previous': page = max(1, page-1)
    return (page, page > 1, page < pages)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('empty', solve(1, 0, "none"), (0, False, False))
check('shrink', solve(8, 3, "none"), (3, True, False))
check('zero', solve(0, 3, "none"), (1, False, True))
check('last', solve(1, 5, "last"), (5, True, False))
check('next end', solve(5, 5, "next"), (5, True, False))
check('next step', solve(1, 5, "next"), (2, True, True))
check('previous start', solve(1, 5, "previous"), (1, False, True))
check('previous step', solve(4, 5, "previous"), (3, True, True))
check('parameterized page count', solve(N,N+1,'next'), (N+1,True,False))
for repetition in range(N):
    check('repeat previous step', solve(4, 5, "previous"), (3, True, True))
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
empty[0, False, False][0, False, False]Passed
shrink[3, True, False][3, True, False]Passed
zero[1, False, True][1, False, True]Passed
last[5, True, False][5, True, False]Passed
next end[5, True, False][5, True, False]Passed
next step[2, True, True][2, True, True]Passed
previous start[1, False, True][1, False, True]Passed
previous step[3, True, True][3, True, True]Passed
parameterized page count[2, True, False][2, True, False]Passed
repeat previous step[3, True, True][3, True, True]Passed

SHA-256 / b951dc12a6c5ce84698c933b420469b0337a7ae5a61b305a1f11f138fc9b3580

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:22.848244+00:00.

Case digest / aad413e2427db84f975b80296025d20c93bd2d2d6797701fe6f6c08fc88d5518