FAILURE MAP
← Case archive

FA-8716 / Notification interfaces / Open access

Toast queue lifecycle: Updating one toast overwrites all toast messages · case 01

Updating one toast overwrites all toast messages.

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

ROOT CAUSE

The update operation uses `if True: x['message'] = message` where the contract requires `if x['id'] == ident: x['message'] = message`.

VERIFIED REPAIR

Implement the update operation as `if x['id'] == ident: x['message'] = message`.

Unsuccessful approach: Reversing identity updates only unrelated notifications.

Case contract

Toast IDs deduplicate additions; equal content may belong to distinct IDs; keep newest within capacity; update/dismiss target one ID; clear removes all.

Why this case matters

A deterministic model of toast queue lifecycle; 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(items, event, ident, message, limit):
    items = [dict(x) for x in items]
    if event == 'add':
        if any(x['id'] == ident for x in items): return items
        items.append({'id': ident, 'message': message})
        return items[-limit:] if limit else []
    if event == 'update':
        for x in items:
            if True: x['message'] = message
    if event == 'dismiss': items = [x for x in items if x['id'] != ident]
    if event == 'clear': items = []
    return items
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('distinct messages equal', solve([dict(id='a',message='same')], 'add', 'b', 'same', 3), [{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}])
check('retry identity', solve([dict(id='a',message='first')], 'add', 'a', 'new', 3), [{'id': 'a', 'message': 'first'}])
check('capacity', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'add', 'c', 'c', 2), [{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}])
check('zero', solve([], 'add', 'a', 'a', 0), [])
check('update', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'update', 'a', 'new', 3), [{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}])
check('dismiss', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'dismiss', 'a', None, 3), [{'id': 'b', 'message': 'b'}])
check('clear', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'clear', None, None, 3), [])
check('parameterized toast identity', solve([], 'add', str(N), 'message'+str(N), 2), [dict(id=str(N),message='message'+str(N))])
for repetition in range(N):
    check('repeat clear', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'clear', None, None, 3), [])
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
distinct messages equal[{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}][{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}]Passed
retry identity[{'id': 'a', 'message': 'first'}][{'id': 'a', 'message': 'first'}]Passed
capacity[{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}][{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}]Passed
zero[][]Passed
update[{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'new'}][{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}]Failed
dismiss[{'id': 'b', 'message': 'b'}][{'id': 'b', 'message': 'b'}]Passed
clear[][]Passed
parameterized toast identity[{'id': '1', 'message': 'message1'}][{'id': '1', 'message': 'message1'}]Passed
repeat clear[][]Passed

SHA-256 / 9a19bbf97dd023947a55d129eb120c82328528b7ba23739f4f42fa8d6735c0c4

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(items, event, ident, message, limit):
    items = [dict(x) for x in items]
    if event == 'add':
        if any(x['id'] == ident for x in items): return items
        items.append({'id': ident, 'message': message})
        return items[-limit:] if limit else []
    if event == 'update':
        for x in items:
            if x['id'] != ident: x['message'] = message
    if event == 'dismiss': items = [x for x in items if x['id'] != ident]
    if event == 'clear': items = []
    return items
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('distinct messages equal', solve([dict(id='a',message='same')], 'add', 'b', 'same', 3), [{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}])
check('retry identity', solve([dict(id='a',message='first')], 'add', 'a', 'new', 3), [{'id': 'a', 'message': 'first'}])
check('capacity', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'add', 'c', 'c', 2), [{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}])
check('zero', solve([], 'add', 'a', 'a', 0), [])
check('update', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'update', 'a', 'new', 3), [{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}])
check('dismiss', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'dismiss', 'a', None, 3), [{'id': 'b', 'message': 'b'}])
check('clear', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'clear', None, None, 3), [])
check('parameterized toast identity', solve([], 'add', str(N), 'message'+str(N), 2), [dict(id=str(N),message='message'+str(N))])
for repetition in range(N):
    check('repeat clear', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'clear', None, None, 3), [])
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
distinct messages equal[{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}][{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}]Passed
retry identity[{'id': 'a', 'message': 'first'}][{'id': 'a', 'message': 'first'}]Passed
capacity[{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}][{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}]Passed
zero[][]Passed
update[{'id': 'a', 'message': 'a'}, {'id': 'b', 'message': 'new'}][{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}]Failed
dismiss[{'id': 'b', 'message': 'b'}][{'id': 'b', 'message': 'b'}]Passed
clear[][]Passed
parameterized toast identity[{'id': '1', 'message': 'message1'}][{'id': '1', 'message': 'message1'}]Passed
repeat clear[][]Passed

SHA-256 / f32beb446d3a7ee7cf1f6489122c2eda7af2e280b0e30af78f1f3c8b84f94ce9

3 / The verified repair

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

N = 1
observations = []
def solve(items, event, ident, message, limit):
    items = [dict(x) for x in items]
    if event == 'add':
        if any(x['id'] == ident for x in items): return items
        items.append({'id': ident, 'message': message})
        return items[-limit:] if limit else []
    if event == 'update':
        for x in items:
            if x['id'] == ident: x['message'] = message
    if event == 'dismiss': items = [x for x in items if x['id'] != ident]
    if event == 'clear': items = []
    return items
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('distinct messages equal', solve([dict(id='a',message='same')], 'add', 'b', 'same', 3), [{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}])
check('retry identity', solve([dict(id='a',message='first')], 'add', 'a', 'new', 3), [{'id': 'a', 'message': 'first'}])
check('capacity', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'add', 'c', 'c', 2), [{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}])
check('zero', solve([], 'add', 'a', 'a', 0), [])
check('update', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'update', 'a', 'new', 3), [{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}])
check('dismiss', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'dismiss', 'a', None, 3), [{'id': 'b', 'message': 'b'}])
check('clear', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'clear', None, None, 3), [])
check('parameterized toast identity', solve([], 'add', str(N), 'message'+str(N), 2), [dict(id=str(N),message='message'+str(N))])
for repetition in range(N):
    check('repeat clear', solve([dict(id='a',message='a'),dict(id='b',message='b')], 'clear', None, None, 3), [])
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
distinct messages equal[{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}][{'id': 'a', 'message': 'same'}, {'id': 'b', 'message': 'same'}]Passed
retry identity[{'id': 'a', 'message': 'first'}][{'id': 'a', 'message': 'first'}]Passed
capacity[{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}][{'id': 'b', 'message': 'b'}, {'id': 'c', 'message': 'c'}]Passed
zero[][]Passed
update[{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}][{'id': 'a', 'message': 'new'}, {'id': 'b', 'message': 'b'}]Passed
dismiss[{'id': 'b', 'message': 'b'}][{'id': 'b', 'message': 'b'}]Passed
clear[][]Passed
parameterized toast identity[{'id': '1', 'message': 'message1'}][{'id': '1', 'message': 'message1'}]Passed
repeat clear[][]Passed

SHA-256 / 264ec16a1f876512909a8d200575a53132141ed7db2a5e403fcc7d6edd0f0a15

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

Case digest / 28ef744f27000f878ad76b395219049fc087ed099da16ea8aacd25fc00ed7a92