FAILURE MAP
← Case archive

FA-30766 / HTTP retries / Open access

Stable client operation identity over retries: Stable retry key violates retry transition semantics · case 01

Stable retry key violates retry transition semantics

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

ROOT CAUSE

Stable retry key violates retry transition semantics

VERIFIED REPAIR

Restore the specified transition out.append([key,original]).

Unsuccessful approach: The attempted repair changes the faulty site to out.append([serial,original]) but still violates a regression oracle.

Case contract

begin(provided key or None,body) starts a logical operation and advances a local operation serial. Generated key is operation serial; explicit keys including zero remain exact. send(body) first sends only matching snapshotted body. uncertain authorizes a resend; reject is terminal; success is terminal. Retried sends reuse the initial key. Return sent key/body pairs or refusal reason.

Why this case matters

Offline deterministic model of HTTP request retries.

1 / The failure

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

N = 1
observations = []
def solve(events):
    serial=0; key=None; original=None; state='idle'; out=[]
    for e in events:
        if e[0]=='begin':
            serial+=1
            key=serial if e[1] is None else e[1]
            original=e[2]
            state='ready'
        elif e[0]=='send':
            if state not in ('ready','uncertain'): out.append('blocked'); continue
            if e[1]!=original: out.append('body-conflict'); continue
            out.append([serial+len(out),original])
            state='sent'
        elif e[0]=='uncertain':
            if state=='sent': state='uncertain'
        elif e[0]=='reject': state='rejected'
        elif e[0]=='success':
            if state=='sent': state='done'
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('begin',None,N),('send',N),('uncertain',),('send',N),('send',N),('success',),('uncertain',),('send',N)]), [[1,N],[1,N],'blocked','blocked'])
check('2', solve([('begin',0,N),('send',N)]), [[0,N]])
check('3', solve([('begin','customer-key',N),('send',N),('uncertain',),('send',N+1),('send',N)]), [['customer-key',N],'body-conflict',['customer-key',N]])
check('4', solve([('begin',None,N),('send',N),('reject',),('uncertain',),('send',N),('begin',None,N+1),('send',N+1)]), [[1,N],'blocked',[2,N+1]])
check('5', solve([('begin',None,N),('send',N+1),('send',N)]), ['body-conflict',[1,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
0[][]Passed
1[[1, 1], [2, 1], 'blocked', 'blocked'][[1, 1], [1, 1], 'blocked', 'blocked']Failed
2[[1, 1]][[0, 1]]Failed
3[[1, 1], 'body-conflict', [3, 1]][['customer-key', 1], 'body-conflict', ['customer-key', 1]]Failed
4[[1, 1], 'blocked', [4, 2]][[1, 1], 'blocked', [2, 2]]Failed
5['body-conflict', [2, 1]]['body-conflict', [1, 1]]Failed

SHA-256 / 31163150a9f90f118b99e2af0764e92364e5f485782704b046dd9d9b034f97b4

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(events):
    serial=0; key=None; original=None; state='idle'; out=[]
    for e in events:
        if e[0]=='begin':
            serial+=1
            key=serial if e[1] is None else e[1]
            original=e[2]
            state='ready'
        elif e[0]=='send':
            if state not in ('ready','uncertain'): out.append('blocked'); continue
            if e[1]!=original: out.append('body-conflict'); continue
            out.append([serial,original])
            state='sent'
        elif e[0]=='uncertain':
            if state=='sent': state='uncertain'
        elif e[0]=='reject': state='rejected'
        elif e[0]=='success':
            if state=='sent': state='done'
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('begin',None,N),('send',N),('uncertain',),('send',N),('send',N),('success',),('uncertain',),('send',N)]), [[1,N],[1,N],'blocked','blocked'])
check('2', solve([('begin',0,N),('send',N)]), [[0,N]])
check('3', solve([('begin','customer-key',N),('send',N),('uncertain',),('send',N+1),('send',N)]), [['customer-key',N],'body-conflict',['customer-key',N]])
check('4', solve([('begin',None,N),('send',N),('reject',),('uncertain',),('send',N),('begin',None,N+1),('send',N+1)]), [[1,N],'blocked',[2,N+1]])
check('5', solve([('begin',None,N),('send',N+1),('send',N)]), ['body-conflict',[1,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
0[][]Passed
1[[1, 1], [1, 1], 'blocked', 'blocked'][[1, 1], [1, 1], 'blocked', 'blocked']Passed
2[[1, 1]][[0, 1]]Failed
3[[1, 1], 'body-conflict', [1, 1]][['customer-key', 1], 'body-conflict', ['customer-key', 1]]Failed
4[[1, 1], 'blocked', [2, 2]][[1, 1], 'blocked', [2, 2]]Passed
5['body-conflict', [1, 1]]['body-conflict', [1, 1]]Passed

SHA-256 / f75e12fcc8c321c7766d388e7443262d42fe07c0ebe3731e9227a445aae799a0

3 / The verified repair

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

N = 1
observations = []
def solve(events):
    serial=0; key=None; original=None; state='idle'; out=[]
    for e in events:
        if e[0]=='begin':
            serial+=1
            key=serial if e[1] is None else e[1]
            original=e[2]
            state='ready'
        elif e[0]=='send':
            if state not in ('ready','uncertain'): out.append('blocked'); continue
            if e[1]!=original: out.append('body-conflict'); continue
            out.append([key,original])
            state='sent'
        elif e[0]=='uncertain':
            if state=='sent': state='uncertain'
        elif e[0]=='reject': state='rejected'
        elif e[0]=='success':
            if state=='sent': state='done'
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('begin',None,N),('send',N),('uncertain',),('send',N),('send',N),('success',),('uncertain',),('send',N)]), [[1,N],[1,N],'blocked','blocked'])
check('2', solve([('begin',0,N),('send',N)]), [[0,N]])
check('3', solve([('begin','customer-key',N),('send',N),('uncertain',),('send',N+1),('send',N)]), [['customer-key',N],'body-conflict',['customer-key',N]])
check('4', solve([('begin',None,N),('send',N),('reject',),('uncertain',),('send',N),('begin',None,N+1),('send',N+1)]), [[1,N],'blocked',[2,N+1]])
check('5', solve([('begin',None,N),('send',N+1),('send',N)]), ['body-conflict',[1,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
0[][]Passed
1[[1, 1], [1, 1], 'blocked', 'blocked'][[1, 1], [1, 1], 'blocked', 'blocked']Passed
2[[0, 1]][[0, 1]]Passed
3[['customer-key', 1], 'body-conflict', ['customer-key', 1]][['customer-key', 1], 'body-conflict', ['customer-key', 1]]Passed
4[[1, 1], 'blocked', [2, 2]][[1, 1], 'blocked', [2, 2]]Passed
5['body-conflict', [1, 1]]['body-conflict', [1, 1]]Passed

SHA-256 / ec41f3138206461d49f6277fef0175725ab149b3c379cbf40b672ebdbc1314c2

Verification & scope

Stipulated bounded simulator, not a complete HTTP implementation or a standards conformance claim. 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:41:55.855187+00:00.

Case digest / d49ea696e2f12da959ecd9238f0f7d59c8b50a0951346da8e1b1cc0538758594