FAILURE MAP
← Case archive

FA-95271 / Warehouse slotting and bin packing / Open access

UOM breakdown: remainder reduced by unit count · case 01

After picking cases the remaining eaches are overstated and extra eaches are requested.

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

ROOT CAUSE

The remainder is decremented by the number of units instead of units times pack size.

THE FAILURE

The remainder is decremented by the number of units instead of units times pack size.

Unsuccessful approach: Subtracting one pack size ignores counts greater than one.

Case contract

qty eaches; pack [eaches per inner, per case, per pallet] with 0 meaning the level does not exist; allowed unit codes for the pick location. Greedy from largest allowed defined unit: PAL, CS, IP, EA. Return [[unit, count]] for nonzero counts in that order, then ["UNPICKABLE", eaches] if a remainder cannot be expressed.

Why this case matters

Pick tasks are expressed in the largest unit a location can present.

1 / The failure

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

N = 1
observations = []
def solve(qty, pack, allowed):
    levels = [('PAL', pack[2]), ('CS', pack[1]), ('IP', pack[0]), ('EA', 1)]
    rem = qty
    out = []
    for unit, size in levels:
        if unit not in allowed or size <= 0:
            continue
        n = rem // size
        if n:
            out.append([unit, n])
            rem -= n
    if rem:
        out.append(['UNPICKABLE', rem])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['full breakdown', [251, [6, 24, 240], ['PAL', 'CS', 'IP', 'EA']], [['PAL', 1], ['IP', 1], ['EA', 5]]], ['case and each', [50, [6, 24, 0], ['CS', 'EA']], [['CS', 2], ['EA', 2]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['zero qty', [0, [6, 24, 240], ['EA']], []], ['pallet not allowed', [500, [6, 24, 240], ['CS', 'EA']], [['CS', 20], ['EA', 20]]], ['undefined inner', [13, [0, 12, 0], ['IP', 'EA']], [['EA', 13]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['generated mix 8', [1000, [0, 48, 0], ['CS', 'IP']], [['CS', 20], ['UNPICKABLE', 40]]]], [['generated mix 8', [1000, [0, 48, 0], ['CS', 'IP']], [['CS', 20], ['UNPICKABLE', 40]]], ['generated mix 1', [3, [4, 12, 120], ['CS', 'IP', 'EA']], [['EA', 3]]], ['undefined inner', [13, [0, 12, 0], ['IP', 'EA']], [['EA', 13]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['full breakdown', [251, [6, 24, 240], ['PAL', 'CS', 'IP', 'EA']], [['PAL', 1], ['IP', 1], ['EA', 5]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['generated mix 11', [250, [0, 48, 0], ['PAL', 'CS']], [['CS', 5], ['UNPICKABLE', 10]]], ['generated mix 19', [500, [0, 48, 480], ['PAL', 'CS', 'EA']], [['PAL', 1], ['EA', 20]]]], [['generated mix 15', [250, [4, 24, 480], ['PAL', 'IP', 'EA']], [['IP', 62], ['EA', 2]]], ['generated mix 8', [1000, [0, 48, 0], ['CS', 'IP']], [['CS', 20], ['UNPICKABLE', 40]]], ['pallet not allowed', [500, [6, 24, 240], ['CS', 'EA']], [['CS', 20], ['EA', 20]]], ['case and each', [50, [6, 24, 0], ['CS', 'EA']], [['CS', 2], ['EA', 2]]], ['undefined inner', [13, [0, 12, 0], ['IP', 'EA']], [['EA', 13]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['generated mix 22', [0, [6, 24, 480], ['CS', 'EA']], []], ['generated mix 30', [13, [4, 12, 240], ['PAL', 'IP', 'EA']], [['IP', 3], ['EA', 1]]]], [['generated mix 25', [50, [6, 24, 0], ['PAL', 'CS', 'IP', 'EA']], [['CS', 2], ['EA', 2]]], ['generated mix 15', [250, [4, 24, 480], ['PAL', 'IP', 'EA']], [['IP', 62], ['EA', 2]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['zero qty', [0, [6, 24, 240], ['EA']], []], ['pallet not allowed', [500, [6, 24, 240], ['CS', 'EA']], [['CS', 20], ['EA', 20]]], ['case and each', [50, [6, 24, 0], ['CS', 'EA']], [['CS', 2], ['EA', 2]]], ['generated mix 33', [1000, [4, 12, 0], ['CS', 'IP', 'EA']], [['CS', 83], ['IP', 1]]], ['generated mix 41', [24, [4, 48, 480], ['CS', 'IP']], [['IP', 6]]]], [['generated mix 35', [250, [0, 24, 0], ['PAL', 'CS', 'IP', 'EA']], [['CS', 10], ['EA', 10]]], ['generated mix 21', [250, [6, 12, 120], ['PAL', 'IP', 'EA']], [['PAL', 2], ['IP', 1], ['EA', 4]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['full breakdown', [251, [6, 24, 240], ['PAL', 'CS', 'IP', 'EA']], [['PAL', 1], ['IP', 1], ['EA', 5]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['zero qty', [0, [6, 24, 240], ['EA']], []], ['generated mix 44', [1000, [0, 12, 240], ['CS', 'IP']], [['CS', 83], ['UNPICKABLE', 4]]], ['generated mix 52', [50, [4, 48, 0], ['EA']], [['EA', 50]]]]]
for label, args, expected in fixtures[N-1]:
    check(label, 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
full breakdown[['PAL', 1], ['CS', 10], ['IP', 40], ['EA', 200]][['PAL', 1], ['IP', 1], ['EA', 5]]Failed
case and each[['CS', 2], ['EA', 48]][['CS', 2], ['EA', 2]]Failed
no each picking[['CS', 2], ['IP', 8], ['UNPICKABLE', 40]][['CS', 2], ['UNPICKABLE', 2]]Failed
zero qty[][]Passed
pallet not allowed[['CS', 20], ['EA', 480]][['CS', 20], ['EA', 20]]Failed
undefined inner[['EA', 13]][['EA', 13]]Passed
inner only[['IP', 3], ['UNPICKABLE', 10]][['IP', 3], ['UNPICKABLE', 1]]Failed
generated mix 8[['CS', 20], ['UNPICKABLE', 980]][['CS', 20], ['UNPICKABLE', 40]]Failed

SHA-256 / 01b14ca75a040c5d485d13a637c94f63642896b72cf730a1b8710e2f9046bb5c

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(qty, pack, allowed):
    levels = [('PAL', pack[2]), ('CS', pack[1]), ('IP', pack[0]), ('EA', 1)]
    rem = qty
    out = []
    for unit, size in levels:
        if unit not in allowed or size <= 0:
            continue
        n = rem // size
        if n:
            out.append([unit, n])
            rem -= size
    if rem:
        out.append(['UNPICKABLE', rem])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['full breakdown', [251, [6, 24, 240], ['PAL', 'CS', 'IP', 'EA']], [['PAL', 1], ['IP', 1], ['EA', 5]]], ['case and each', [50, [6, 24, 0], ['CS', 'EA']], [['CS', 2], ['EA', 2]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['zero qty', [0, [6, 24, 240], ['EA']], []], ['pallet not allowed', [500, [6, 24, 240], ['CS', 'EA']], [['CS', 20], ['EA', 20]]], ['undefined inner', [13, [0, 12, 0], ['IP', 'EA']], [['EA', 13]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['generated mix 8', [1000, [0, 48, 0], ['CS', 'IP']], [['CS', 20], ['UNPICKABLE', 40]]]], [['generated mix 8', [1000, [0, 48, 0], ['CS', 'IP']], [['CS', 20], ['UNPICKABLE', 40]]], ['generated mix 1', [3, [4, 12, 120], ['CS', 'IP', 'EA']], [['EA', 3]]], ['undefined inner', [13, [0, 12, 0], ['IP', 'EA']], [['EA', 13]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['full breakdown', [251, [6, 24, 240], ['PAL', 'CS', 'IP', 'EA']], [['PAL', 1], ['IP', 1], ['EA', 5]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['generated mix 11', [250, [0, 48, 0], ['PAL', 'CS']], [['CS', 5], ['UNPICKABLE', 10]]], ['generated mix 19', [500, [0, 48, 480], ['PAL', 'CS', 'EA']], [['PAL', 1], ['EA', 20]]]], [['generated mix 15', [250, [4, 24, 480], ['PAL', 'IP', 'EA']], [['IP', 62], ['EA', 2]]], ['generated mix 8', [1000, [0, 48, 0], ['CS', 'IP']], [['CS', 20], ['UNPICKABLE', 40]]], ['pallet not allowed', [500, [6, 24, 240], ['CS', 'EA']], [['CS', 20], ['EA', 20]]], ['case and each', [50, [6, 24, 0], ['CS', 'EA']], [['CS', 2], ['EA', 2]]], ['undefined inner', [13, [0, 12, 0], ['IP', 'EA']], [['EA', 13]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['generated mix 22', [0, [6, 24, 480], ['CS', 'EA']], []], ['generated mix 30', [13, [4, 12, 240], ['PAL', 'IP', 'EA']], [['IP', 3], ['EA', 1]]]], [['generated mix 25', [50, [6, 24, 0], ['PAL', 'CS', 'IP', 'EA']], [['CS', 2], ['EA', 2]]], ['generated mix 15', [250, [4, 24, 480], ['PAL', 'IP', 'EA']], [['IP', 62], ['EA', 2]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['zero qty', [0, [6, 24, 240], ['EA']], []], ['pallet not allowed', [500, [6, 24, 240], ['CS', 'EA']], [['CS', 20], ['EA', 20]]], ['case and each', [50, [6, 24, 0], ['CS', 'EA']], [['CS', 2], ['EA', 2]]], ['generated mix 33', [1000, [4, 12, 0], ['CS', 'IP', 'EA']], [['CS', 83], ['IP', 1]]], ['generated mix 41', [24, [4, 48, 480], ['CS', 'IP']], [['IP', 6]]]], [['generated mix 35', [250, [0, 24, 0], ['PAL', 'CS', 'IP', 'EA']], [['CS', 10], ['EA', 10]]], ['generated mix 21', [250, [6, 12, 120], ['PAL', 'IP', 'EA']], [['PAL', 2], ['IP', 1], ['EA', 4]]], ['inner only', [13, [4, 12, 0], ['IP']], [['IP', 3], ['UNPICKABLE', 1]]], ['full breakdown', [251, [6, 24, 240], ['PAL', 'CS', 'IP', 'EA']], [['PAL', 1], ['IP', 1], ['EA', 5]]], ['no each picking', [50, [6, 24, 0], ['CS', 'IP']], [['CS', 2], ['UNPICKABLE', 2]]], ['zero qty', [0, [6, 24, 240], ['EA']], []], ['generated mix 44', [1000, [0, 12, 240], ['CS', 'IP']], [['CS', 83], ['UNPICKABLE', 4]]], ['generated mix 52', [50, [4, 48, 0], ['EA']], [['EA', 50]]]]]
for label, args, expected in fixtures[N-1]:
    check(label, 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
full breakdown[['PAL', 1], ['IP', 1], ['EA', 5], ['UNPICKABLE', 4]][['PAL', 1], ['IP', 1], ['EA', 5]]Failed
case and each[['CS', 2], ['EA', 26], ['UNPICKABLE', 25]][['CS', 2], ['EA', 2]]Failed
no each picking[['CS', 2], ['IP', 4], ['UNPICKABLE', 20]][['CS', 2], ['UNPICKABLE', 2]]Failed
zero qty[][]Passed
pallet not allowed[['CS', 20], ['EA', 476], ['UNPICKABLE', 475]][['CS', 20], ['EA', 20]]Failed
undefined inner[['EA', 13], ['UNPICKABLE', 12]][['EA', 13]]Failed
inner only[['IP', 3], ['UNPICKABLE', 9]][['IP', 3], ['UNPICKABLE', 1]]Failed
generated mix 8[['CS', 20], ['UNPICKABLE', 952]][['CS', 20], ['UNPICKABLE', 40]]Failed

SHA-256 / 08493ced64dd9befcc7500de82ccc3d6a1a29ca737d149cf383e48381fc61b88

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

Greedy stipulated conversion with integer pack sizes. 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:52:12.187622+00:00.

Case digest / 4b8f9fd4808b055aa71f3683728100bf769d2e7c944f4f33faf56bc7d989f1d5