FAILURE MAP
← Case archive

FA-76341 / Email MIME structure / Open access

Pick the part to render from multipart/alternative: last supported wins · case 01

The plain-text alternative is shown although a richer supported alternative follows it.

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

ROOT CAUSE

The last supported wins decision evaluates `best = i if best is None else best` where the contract requires `best = i`.

VERIFIED REPAIR

Use `best = i` for the last supported wins decision and keep every other rule of the model unchanged.

Unsuccessful approach: Preferring HTML specifically still ignores a later, richer supported format. The attempted `best = i if t == 'text/html' or best is None else best` still disagrees with a fixture.

Case contract

Alternatives are ordered by increasing fidelity, so the LAST part whose effective type is in `supported` wins. A multipart/related alternative counts as its root type: the child whose cid equals the start parameter (which carries angle brackets, cids are stored bare) or else the first child. A text/* part is only renderable when its charset (default us-ascii, case-insensitive) is us-ascii, utf-8 or iso-8859-1. With nothing renderable the first part is shown as a fallback. Result {index, type, fallback}.

Why this case matters

Choosing the wrong alternative shows raw markup, a degraded body or an unreadable charset to the reader.

1 / The failure

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

N = 1
observations = []
def solve(part, supported):
    def effective(p):
        if p['type'] == 'multipart/related':
            start = p.get('params', {}).get('start')
            for c in p['parts']:
                if start is not None and c.get('cid') == start.strip('<>'):
                    return c['type']
            return p['parts'][0]['type'] if p['parts'] else None
        return p['type']
    ok_charsets = ('us-ascii', 'utf-8', 'iso-8859-1')
    best = None
    for i, p in enumerate(part['parts']):
        t = effective(p)
        cs = p.get('params', {}).get('charset', 'us-ascii').lower()
        if t in supported and (not t.startswith('text/') or cs in ok_charsets):
            best = i if best is None else best
    if best is None:
        return {'index': 0, 'type': effective(part['parts'][0]), 'fallback': True}
    return {'index': best, 'type': effective(part['parts'][best]), 'fallback': False}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown1'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root1@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root1@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 2: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown2'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root2@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root2@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'UTF-8'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 3: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown3'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root3@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root3@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 4: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown4'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root4@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root4@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'UTF-8'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 5: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown5'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root5@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root5@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})]}
for _label, _args, _expected in _CASES[N]:
    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
richest supported last{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}Failed
unsupported last part{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 1, 'type': 'text/html'}Failed
related root via start{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 1, 'type': 'text/html'}Failed
upper-case charset{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 1, 'type': 'text/html'}Failed
missing charset{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 1, 'type': 'text/html'}Failed
unknown charset html{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 0, 'type': 'text/plain'}Passed
nothing supported{'fallback': True, 'index': 0, 'type': 'application/x-foo'}{'fallback': True, 'index': 0, 'type': 'application/x-foo'}Passed

SHA-256 / 2a83109c62c434cad3a867bbb64b452547a9420af04fb07d50e976cfde0eaf83

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(part, supported):
    def effective(p):
        if p['type'] == 'multipart/related':
            start = p.get('params', {}).get('start')
            for c in p['parts']:
                if start is not None and c.get('cid') == start.strip('<>'):
                    return c['type']
            return p['parts'][0]['type'] if p['parts'] else None
        return p['type']
    ok_charsets = ('us-ascii', 'utf-8', 'iso-8859-1')
    best = None
    for i, p in enumerate(part['parts']):
        t = effective(p)
        cs = p.get('params', {}).get('charset', 'us-ascii').lower()
        if t in supported and (not t.startswith('text/') or cs in ok_charsets):
            best = i if t == 'text/html' or best is None else best
    if best is None:
        return {'index': 0, 'type': effective(part['parts'][0]), 'fallback': True}
    return {'index': best, 'type': effective(part['parts'][best]), 'fallback': False}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown1'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root1@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root1@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 2: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown2'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root2@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root2@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'UTF-8'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 3: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown3'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root3@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root3@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 4: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown4'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root4@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root4@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'UTF-8'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 5: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown5'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root5@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root5@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})]}
for _label, _args, _expected in _CASES[N]:
    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
richest supported last{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}Failed
unsupported last part{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
related root via start{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
upper-case charset{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
missing charset{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
unknown charset html{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 0, 'type': 'text/plain'}Passed
nothing supported{'fallback': True, 'index': 0, 'type': 'application/x-foo'}{'fallback': True, 'index': 0, 'type': 'application/x-foo'}Passed

SHA-256 / 27f8995e4215a169be9ed15ac990b505a4558db9610f980fa3316be6f909c1a0

3 / The verified repair

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

N = 1
observations = []
def solve(part, supported):
    def effective(p):
        if p['type'] == 'multipart/related':
            start = p.get('params', {}).get('start')
            for c in p['parts']:
                if start is not None and c.get('cid') == start.strip('<>'):
                    return c['type']
            return p['parts'][0]['type'] if p['parts'] else None
        return p['type']
    ok_charsets = ('us-ascii', 'utf-8', 'iso-8859-1')
    best = None
    for i, p in enumerate(part['parts']):
        t = effective(p)
        cs = p.get('params', {}).get('charset', 'us-ascii').lower()
        if t in supported and (not t.startswith('text/') or cs in ok_charsets):
            best = i
    if best is None:
        return {'index': 0, 'type': effective(part['parts'][0]), 'fallback': True}
    return {'index': best, 'type': effective(part['parts'][best]), 'fallback': False}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown1'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root1@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root1@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 2: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown2'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root2@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root2@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'UTF-8'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 3: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown3'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root3@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root3@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 4: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown4'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root4@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root4@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'UTF-8'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})], 5: [('richest supported last', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-amp-html'}]}, ['text/plain', 'text/html', 'text/x-amp-html']), {'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}), ('unsupported last part', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}, {'type': 'text/x-unknown5'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('related root via start', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'multipart/related', 'params': {'start': '<root5@x>'}, 'parts': [{'type': 'image/png', 'cid': 'img@x'}, {'type': 'text/html', 'cid': 'root5@x'}]}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('upper-case charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'params': {'charset': 'UTF-8'}}, {'type': 'text/html', 'params': {'charset': 'ISO-8859-1'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('missing charset', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html'}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 1, 'type': 'text/html'}), ('unknown charset html', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain'}, {'type': 'text/html', 'params': {'charset': 'x-klingon'}}]}, ['text/plain', 'text/html']), {'fallback': False, 'index': 0, 'type': 'text/plain'}), ('nothing supported', ({'type': 'multipart/alternative', 'parts': [{'type': 'application/x-foo'}, {'type': 'text/x-bar'}]}, ['text/plain']), {'fallback': True, 'index': 0, 'type': 'application/x-foo'})]}
for _label, _args, _expected in _CASES[N]:
    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
richest supported last{'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}{'fallback': False, 'index': 2, 'type': 'text/x-amp-html'}Passed
unsupported last part{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
related root via start{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
upper-case charset{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
missing charset{'fallback': False, 'index': 1, 'type': 'text/html'}{'fallback': False, 'index': 1, 'type': 'text/html'}Passed
unknown charset html{'fallback': False, 'index': 0, 'type': 'text/plain'}{'fallback': False, 'index': 0, 'type': 'text/plain'}Passed
nothing supported{'fallback': True, 'index': 0, 'type': 'application/x-foo'}{'fallback': True, 'index': 0, 'type': 'application/x-foo'}Passed

SHA-256 / 2aedc2c63759913515e0d457a408af5dfedb8aa56be4c947e76fe1d6860e4b29

Verification & scope

Stipulated offline model over pre-parsed MIME dictionaries; not a conforming MIME parser, generator or mail client. 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:15.435869+00:00.

Case digest / 2a3d7770a5633898f4be0f60bfa57d1ed1d4bf55364a977da954601656ed8dae