FAILURE MAP
← Case archive

FA-79396 / Barcode symbology encoding / Open access

Code 128 start set is chosen from the total digit count · case 01

Data such as "A1B2C3D4" starts in set C and immediately needs a switch, producing a longer symbol.

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

ROOT CAUSE

The start decision counts every digit in the data instead of the run at the beginning.

VERIFIED REPAIR

Measure only the digit run that starts at position 0.

Unsuccessful approach: Using the longest run anywhere still starts in C for data that begins with letters.

Case contract

Plan Code 128 code sets for printable ASCII data (other characters -> None) as a list of [set, text] segments. Start in C when the data begins with at least 4 digits or is entirely digits of even length >= 2, else B. In C consume digit pairs and fall back to B when fewer than two digits remain in the run. In B switch to C before a run of at least 6 digits, or at least 4 digits that reach the end of the data; an odd run first encodes one digit in B. Empty data yields [["B", ""]].

Why this case matters

Retail, logistics, pharmacy and document workflows depend on encoders that produce exactly the module pattern, code-set switches, separators and quiet zones scanners expect; one misplaced module or separator makes a label unreadable or, worse, scan as different data.

1 / The failure

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

N = 1
observations = []
def solve(data):
    if any(not (32 <= ord(ch) <= 126) for ch in data):
        return None
    n = len(data)
    def run(j):
        k = j
        while k < n and data[k] in '0123456789':
            k += 1
        return k - j
    segs = []
    r = sum(c in '0123456789' for c in data)
    if r >= 4 or (r == n and n >= 2 and n % 2 == 0):
        cur = 'C'
    else:
        cur = 'B'
    buf = ''
    i = 0
    while i < n:
        if cur == 'C':
            if run(i) >= 2:
                buf += data[i:i + 2]
                i += 2
                continue
            segs.append(['C', buf])
            buf = ''
            cur = 'B'
            continue
        r = run(i)
        if r >= 6 or (r >= 4 and i + r == n):
            if r % 2 == 1:
                buf += data[i]
                i += 1
            if buf:
                segs.append(['B', buf])
            buf = ''
            cur = 'C'
            continue
        buf += data[i]
        i += 1
    if buf or not segs:
        segs.append([cur, buf])
    return segs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['lot17764124x', [['B', 'lot'], ['C', '17764124'], ['B', 'x']]], ['Q7 2187698', [['B', 'Q7 2'], ['C', '187698']]], ['3580131', [['C', '358013'], ['B', '1']]], ['xAB', [['B', 'xAB']]], ['AB', [['B', 'AB']]], ['x15', [['B', 'x15']]], ['235623lotQ7', [['C', '235623'], ['B', 'lotQ7']]], [' 193261lot', [['B', ' '], ['C', '193261'], ['B', 'lot']]]], [['-831943095', [['B', '-8'], ['C', '31943095']]], ['lot 27987', [['B', 'lot 2'], ['C', '7987']]], ['Q7lotQ7lot', [['B', 'Q7lotQ7lot']]], ['101874486507729', [['C', '10187448650772'], ['B', '9']]], ['x22', [['B', 'x22']]], [' ', [['B', ' ']]], ['-006', [['B', '-006']]], ['-Q793294lot', [['B', '-Q'], ['C', '793294'], ['B', 'lot']]]], [[' 29428AB ', [['B', ' 29428AB ']]], ['Q7978310878277523004', [['B', 'Q7'], ['C', '978310878277523004']]], ['0964853799773055547674lot', [['C', '0964853799773055547674'], ['B', 'lot']]], ['lot', [['B', 'lot']]], ['1', [['B', '1']]], ['Q7 lotAB', [['B', 'Q7 lotAB']]], ['2921977210', [['C', '2921977210']]], ['-753024468324', [['B', '-'], ['C', '753024468324']]]], [[' 705791-x', [['B', ' '], ['C', '705791'], ['B', '-x']]], ['lot43980115x', [['B', 'lot'], ['C', '43980115'], ['B', 'x']]], ['733-', [['B', '733-']]], ['46450162930', [['C', '4645016293'], ['B', '0']]], [' - ', [['B', ' - ']]], [' Q7', [['B', ' Q7']]], ['14789849620002739', [['C', '1478984962000273'], ['B', '9']]], ['lot5899 ', [['B', 'lot5899 ']]]], [['lotx628901387', [['B', 'lotx6'], ['C', '28901387']]], ['AB47591471059313936x', [['B', 'AB4'], ['C', '7591471059313936'], ['B', 'x']]], ['AB8', [['B', 'AB8']]], ['014550632960 753', [['C', '014550632960'], ['B', ' 753']]], ['3283655059x2996', [['C', '3283655059'], ['B', 'x'], ['C', '2996']]], [' x', [['B', ' x']]], ['2637', [['C', '2637']]], ['lotQ7x4598', [['B', 'lotQ7x'], ['C', '4598']]]]]
labels = ["regression: leading digit run measurement", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
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
regression: leading digit run measurement 0[['C', ''], ['B', 'lot'], ['C', '17764124'], ['B', 'x']][['B', 'lot'], ['C', '17764124'], ['B', 'x']]Failed
repair trap 1[['C', ''], ['B', 'Q7 2'], ['C', '187698']][['B', 'Q7 2'], ['C', '187698']]Failed
combined fault 2[['C', '358013'], ['B', '1']][['C', '358013'], ['B', '1']]Passed
control 3[['B', 'xAB']][['B', 'xAB']]Passed
control 4[['B', 'AB']][['B', 'AB']]Passed
boundary 5[['B', 'x15']][['B', 'x15']]Passed
boundary 6[['C', '235623'], ['B', 'lotQ7']][['C', '235623'], ['B', 'lotQ7']]Passed
control 7[['C', ''], ['B', ' '], ['C', '193261'], ['B', 'lot']][['B', ' '], ['C', '193261'], ['B', 'lot']]Failed

SHA-256 / b86bea51fdcae1c82d537ac78fd6ebf1d5b7b631a8f3bafd2507d6a423b47a13

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(data):
    if any(not (32 <= ord(ch) <= 126) for ch in data):
        return None
    n = len(data)
    def run(j):
        k = j
        while k < n and data[k] in '0123456789':
            k += 1
        return k - j
    segs = []
    r = max(run(j) for j in range(n)) if n else 0
    if r >= 4 or (r == n and n >= 2 and n % 2 == 0):
        cur = 'C'
    else:
        cur = 'B'
    buf = ''
    i = 0
    while i < n:
        if cur == 'C':
            if run(i) >= 2:
                buf += data[i:i + 2]
                i += 2
                continue
            segs.append(['C', buf])
            buf = ''
            cur = 'B'
            continue
        r = run(i)
        if r >= 6 or (r >= 4 and i + r == n):
            if r % 2 == 1:
                buf += data[i]
                i += 1
            if buf:
                segs.append(['B', buf])
            buf = ''
            cur = 'C'
            continue
        buf += data[i]
        i += 1
    if buf or not segs:
        segs.append([cur, buf])
    return segs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['lot17764124x', [['B', 'lot'], ['C', '17764124'], ['B', 'x']]], ['Q7 2187698', [['B', 'Q7 2'], ['C', '187698']]], ['3580131', [['C', '358013'], ['B', '1']]], ['xAB', [['B', 'xAB']]], ['AB', [['B', 'AB']]], ['x15', [['B', 'x15']]], ['235623lotQ7', [['C', '235623'], ['B', 'lotQ7']]], [' 193261lot', [['B', ' '], ['C', '193261'], ['B', 'lot']]]], [['-831943095', [['B', '-8'], ['C', '31943095']]], ['lot 27987', [['B', 'lot 2'], ['C', '7987']]], ['Q7lotQ7lot', [['B', 'Q7lotQ7lot']]], ['101874486507729', [['C', '10187448650772'], ['B', '9']]], ['x22', [['B', 'x22']]], [' ', [['B', ' ']]], ['-006', [['B', '-006']]], ['-Q793294lot', [['B', '-Q'], ['C', '793294'], ['B', 'lot']]]], [[' 29428AB ', [['B', ' 29428AB ']]], ['Q7978310878277523004', [['B', 'Q7'], ['C', '978310878277523004']]], ['0964853799773055547674lot', [['C', '0964853799773055547674'], ['B', 'lot']]], ['lot', [['B', 'lot']]], ['1', [['B', '1']]], ['Q7 lotAB', [['B', 'Q7 lotAB']]], ['2921977210', [['C', '2921977210']]], ['-753024468324', [['B', '-'], ['C', '753024468324']]]], [[' 705791-x', [['B', ' '], ['C', '705791'], ['B', '-x']]], ['lot43980115x', [['B', 'lot'], ['C', '43980115'], ['B', 'x']]], ['733-', [['B', '733-']]], ['46450162930', [['C', '4645016293'], ['B', '0']]], [' - ', [['B', ' - ']]], [' Q7', [['B', ' Q7']]], ['14789849620002739', [['C', '1478984962000273'], ['B', '9']]], ['lot5899 ', [['B', 'lot5899 ']]]], [['lotx628901387', [['B', 'lotx6'], ['C', '28901387']]], ['AB47591471059313936x', [['B', 'AB4'], ['C', '7591471059313936'], ['B', 'x']]], ['AB8', [['B', 'AB8']]], ['014550632960 753', [['C', '014550632960'], ['B', ' 753']]], ['3283655059x2996', [['C', '3283655059'], ['B', 'x'], ['C', '2996']]], [' x', [['B', ' x']]], ['2637', [['C', '2637']]], ['lotQ7x4598', [['B', 'lotQ7x'], ['C', '4598']]]]]
labels = ["regression: leading digit run measurement", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
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
regression: leading digit run measurement 0[['C', ''], ['B', 'lot'], ['C', '17764124'], ['B', 'x']][['B', 'lot'], ['C', '17764124'], ['B', 'x']]Failed
repair trap 1[['C', ''], ['B', 'Q7 2'], ['C', '187698']][['B', 'Q7 2'], ['C', '187698']]Failed
combined fault 2[['C', '358013'], ['B', '1']][['C', '358013'], ['B', '1']]Passed
control 3[['B', 'xAB']][['B', 'xAB']]Passed
control 4[['B', 'AB']][['B', 'AB']]Passed
boundary 5[['B', 'x15']][['B', 'x15']]Passed
boundary 6[['C', '235623'], ['B', 'lotQ7']][['C', '235623'], ['B', 'lotQ7']]Passed
control 7[['C', ''], ['B', ' '], ['C', '193261'], ['B', 'lot']][['B', ' '], ['C', '193261'], ['B', 'lot']]Failed

SHA-256 / 3536adc05d2652ab03938232ccb0a553abb21f9c1bd2843eed503eab7b8761c7

3 / The verified repair

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

N = 1
observations = []
def solve(data):
    if any(not (32 <= ord(ch) <= 126) for ch in data):
        return None
    n = len(data)
    def run(j):
        k = j
        while k < n and data[k] in '0123456789':
            k += 1
        return k - j
    segs = []
    r = run(0)
    if r >= 4 or (r == n and n >= 2 and n % 2 == 0):
        cur = 'C'
    else:
        cur = 'B'
    buf = ''
    i = 0
    while i < n:
        if cur == 'C':
            if run(i) >= 2:
                buf += data[i:i + 2]
                i += 2
                continue
            segs.append(['C', buf])
            buf = ''
            cur = 'B'
            continue
        r = run(i)
        if r >= 6 or (r >= 4 and i + r == n):
            if r % 2 == 1:
                buf += data[i]
                i += 1
            if buf:
                segs.append(['B', buf])
            buf = ''
            cur = 'C'
            continue
        buf += data[i]
        i += 1
    if buf or not segs:
        segs.append([cur, buf])
    return segs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['lot17764124x', [['B', 'lot'], ['C', '17764124'], ['B', 'x']]], ['Q7 2187698', [['B', 'Q7 2'], ['C', '187698']]], ['3580131', [['C', '358013'], ['B', '1']]], ['xAB', [['B', 'xAB']]], ['AB', [['B', 'AB']]], ['x15', [['B', 'x15']]], ['235623lotQ7', [['C', '235623'], ['B', 'lotQ7']]], [' 193261lot', [['B', ' '], ['C', '193261'], ['B', 'lot']]]], [['-831943095', [['B', '-8'], ['C', '31943095']]], ['lot 27987', [['B', 'lot 2'], ['C', '7987']]], ['Q7lotQ7lot', [['B', 'Q7lotQ7lot']]], ['101874486507729', [['C', '10187448650772'], ['B', '9']]], ['x22', [['B', 'x22']]], [' ', [['B', ' ']]], ['-006', [['B', '-006']]], ['-Q793294lot', [['B', '-Q'], ['C', '793294'], ['B', 'lot']]]], [[' 29428AB ', [['B', ' 29428AB ']]], ['Q7978310878277523004', [['B', 'Q7'], ['C', '978310878277523004']]], ['0964853799773055547674lot', [['C', '0964853799773055547674'], ['B', 'lot']]], ['lot', [['B', 'lot']]], ['1', [['B', '1']]], ['Q7 lotAB', [['B', 'Q7 lotAB']]], ['2921977210', [['C', '2921977210']]], ['-753024468324', [['B', '-'], ['C', '753024468324']]]], [[' 705791-x', [['B', ' '], ['C', '705791'], ['B', '-x']]], ['lot43980115x', [['B', 'lot'], ['C', '43980115'], ['B', 'x']]], ['733-', [['B', '733-']]], ['46450162930', [['C', '4645016293'], ['B', '0']]], [' - ', [['B', ' - ']]], [' Q7', [['B', ' Q7']]], ['14789849620002739', [['C', '1478984962000273'], ['B', '9']]], ['lot5899 ', [['B', 'lot5899 ']]]], [['lotx628901387', [['B', 'lotx6'], ['C', '28901387']]], ['AB47591471059313936x', [['B', 'AB4'], ['C', '7591471059313936'], ['B', 'x']]], ['AB8', [['B', 'AB8']]], ['014550632960 753', [['C', '014550632960'], ['B', ' 753']]], ['3283655059x2996', [['C', '3283655059'], ['B', 'x'], ['C', '2996']]], [' x', [['B', ' x']]], ['2637', [['C', '2637']]], ['lotQ7x4598', [['B', 'lotQ7x'], ['C', '4598']]]]]
labels = ["regression: leading digit run measurement", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
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
regression: leading digit run measurement 0[['B', 'lot'], ['C', '17764124'], ['B', 'x']][['B', 'lot'], ['C', '17764124'], ['B', 'x']]Passed
repair trap 1[['B', 'Q7 2'], ['C', '187698']][['B', 'Q7 2'], ['C', '187698']]Passed
combined fault 2[['C', '358013'], ['B', '1']][['C', '358013'], ['B', '1']]Passed
control 3[['B', 'xAB']][['B', 'xAB']]Passed
control 4[['B', 'AB']][['B', 'AB']]Passed
boundary 5[['B', 'x15']][['B', 'x15']]Passed
boundary 6[['C', '235623'], ['B', 'lotQ7']][['C', '235623'], ['B', 'lotQ7']]Passed
control 7[['B', ' '], ['C', '193261'], ['B', 'lot']][['B', ' '], ['C', '193261'], ['B', 'lot']]Passed

SHA-256 / 4687c1e61eebb18bf704d104a4e2464bb57666d7006a895de51a979d4b773fe3

Verification & scope

A deterministic bounded teaching model with a stipulated contract; it makes no claim of conformance to any published specification. 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:49:44.348627+00:00.

Case digest / 3fb70cec9eb8a05cd58003e621afad6d6af6b1af6ef3f873e59ec1e66e2ea479