FAILURE MAP
← Case archive

FA-76576 / Email MIME structure / Open access

Choose the MIME skeleton for an outgoing message: body before attachments · case 01

Attachments precede the body in multipart/mixed, so clients show an attachment as the message.

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

ROOT CAUSE

The body before attachments decision evaluates `['att'] * atts + [body]` where the contract requires `[body] + ['att'] * atts`.

VERIFIED REPAIR

Use `[body] + ['att'] * atts` for the body before attachments decision and keep every other rule of the model unchanged.

Unsuccessful approach: Placing one attachment before the body still puts an attachment first. The attempted `['att'] + [body] + ['att'] * (atts - 1)` still disagrees with a fixture.

Case contract

The body is multipart/alternative(text, html) when both versions exist, the html alone when only html exists, else text. Inline images go into multipart/related with the html root first; without html they become attachments. When there are attachments the result is multipart/mixed(body, attachments...). Output is a compact string such as "mixed(alternative(text,related(html,img)),att)".

Why this case matters

Composing the wrong skeleton makes clients show images as attachments, hide the plain-text version or drop parts.

1 / The failure

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

N = 1
observations = []
def solve(has_text, has_html, inline_images, attachments):
    atts = attachments
    html = None
    if has_html:
        html = 'html' if inline_images == 0 else 'related(' + ','.join(['html'] + ['img'] * inline_images) + ')'
    else:
        atts += inline_images
    if has_text and html:
        body = 'alternative(text,' + html + ')'
    elif html:
        body = html
    else:
        body = 'text'
    if atts:
        return 'mixed(' + ','.join(['att'] * atts + [body]) + ')'
    return body
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('images without html', (False, False, 2, 0), 'mixed(text,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 2, 0), 'alternative(text,related(html,img,img))'), ('html images and attachment', (False, True, 1, 1), 'mixed(related(html,img),att)'), ('text and attachments', (True, False, 0, 1), 'mixed(text,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 1), 'mixed(alternative(text,related(html,img,img)),att)')], 2: [('images without html', (False, False, 3, 0), 'mixed(text,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 3, 0), 'alternative(text,related(html,img,img,img))'), ('html images and attachment', (False, True, 2, 1), 'mixed(related(html,img,img),att)'), ('text and attachments', (True, False, 0, 2), 'mixed(text,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 2), 'mixed(alternative(text,related(html,img,img)),att,att)')], 3: [('images without html', (False, False, 4, 0), 'mixed(text,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 4, 0), 'alternative(text,related(html,img,img,img,img))'), ('html images and attachment', (False, True, 3, 1), 'mixed(related(html,img,img,img),att)'), ('text and attachments', (True, False, 0, 3), 'mixed(text,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 3), 'mixed(alternative(text,related(html,img,img)),att,att,att)')], 4: [('images without html', (False, False, 5, 0), 'mixed(text,att,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 5, 0), 'alternative(text,related(html,img,img,img,img,img))'), ('html images and attachment', (False, True, 4, 1), 'mixed(related(html,img,img,img,img),att)'), ('text and attachments', (True, False, 0, 4), 'mixed(text,att,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 4), 'mixed(alternative(text,related(html,img,img)),att,att,att,att)')], 5: [('images without html', (False, False, 6, 0), 'mixed(text,att,att,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 6, 0), 'alternative(text,related(html,img,img,img,img,img,img))'), ('html images and attachment', (False, True, 5, 1), 'mixed(related(html,img,img,img,img,img),att)'), ('text and attachments', (True, False, 0, 5), 'mixed(text,att,att,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 5), 'mixed(alternative(text,related(html,img,img)),att,att,att,att,att)')]}
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
images without htmlmixed(att,att,text)mixed(text,att,att)Failed
text and htmlalternative(text,html)alternative(text,html)Passed
text html and imagesalternative(text,related(html,img,img))alternative(text,related(html,img,img))Passed
html images and attachmentmixed(att,related(html,img))mixed(related(html,img),att)Failed
text and attachmentsmixed(att,text)mixed(text,att)Failed
plain text onlytexttextPassed
everythingmixed(att,alternative(text,related(html,img,img)))mixed(alternative(text,related(html,img,img)),att)Failed

SHA-256 / 105d450c047f8ff50c1d4cca9537324d7561e24acb8ad99aad54fd237155c378

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(has_text, has_html, inline_images, attachments):
    atts = attachments
    html = None
    if has_html:
        html = 'html' if inline_images == 0 else 'related(' + ','.join(['html'] + ['img'] * inline_images) + ')'
    else:
        atts += inline_images
    if has_text and html:
        body = 'alternative(text,' + html + ')'
    elif html:
        body = html
    else:
        body = 'text'
    if atts:
        return 'mixed(' + ','.join(['att'] + [body] + ['att'] * (atts - 1)) + ')'
    return body
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('images without html', (False, False, 2, 0), 'mixed(text,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 2, 0), 'alternative(text,related(html,img,img))'), ('html images and attachment', (False, True, 1, 1), 'mixed(related(html,img),att)'), ('text and attachments', (True, False, 0, 1), 'mixed(text,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 1), 'mixed(alternative(text,related(html,img,img)),att)')], 2: [('images without html', (False, False, 3, 0), 'mixed(text,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 3, 0), 'alternative(text,related(html,img,img,img))'), ('html images and attachment', (False, True, 2, 1), 'mixed(related(html,img,img),att)'), ('text and attachments', (True, False, 0, 2), 'mixed(text,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 2), 'mixed(alternative(text,related(html,img,img)),att,att)')], 3: [('images without html', (False, False, 4, 0), 'mixed(text,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 4, 0), 'alternative(text,related(html,img,img,img,img))'), ('html images and attachment', (False, True, 3, 1), 'mixed(related(html,img,img,img),att)'), ('text and attachments', (True, False, 0, 3), 'mixed(text,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 3), 'mixed(alternative(text,related(html,img,img)),att,att,att)')], 4: [('images without html', (False, False, 5, 0), 'mixed(text,att,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 5, 0), 'alternative(text,related(html,img,img,img,img,img))'), ('html images and attachment', (False, True, 4, 1), 'mixed(related(html,img,img,img,img),att)'), ('text and attachments', (True, False, 0, 4), 'mixed(text,att,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 4), 'mixed(alternative(text,related(html,img,img)),att,att,att,att)')], 5: [('images without html', (False, False, 6, 0), 'mixed(text,att,att,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 6, 0), 'alternative(text,related(html,img,img,img,img,img,img))'), ('html images and attachment', (False, True, 5, 1), 'mixed(related(html,img,img,img,img,img),att)'), ('text and attachments', (True, False, 0, 5), 'mixed(text,att,att,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 5), 'mixed(alternative(text,related(html,img,img)),att,att,att,att,att)')]}
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
images without htmlmixed(att,text,att)mixed(text,att,att)Failed
text and htmlalternative(text,html)alternative(text,html)Passed
text html and imagesalternative(text,related(html,img,img))alternative(text,related(html,img,img))Passed
html images and attachmentmixed(att,related(html,img))mixed(related(html,img),att)Failed
text and attachmentsmixed(att,text)mixed(text,att)Failed
plain text onlytexttextPassed
everythingmixed(att,alternative(text,related(html,img,img)))mixed(alternative(text,related(html,img,img)),att)Failed

SHA-256 / fb9882353936f01aad6816a126d649048f45ac150756b02660515d625970c486

3 / The verified repair

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

N = 1
observations = []
def solve(has_text, has_html, inline_images, attachments):
    atts = attachments
    html = None
    if has_html:
        html = 'html' if inline_images == 0 else 'related(' + ','.join(['html'] + ['img'] * inline_images) + ')'
    else:
        atts += inline_images
    if has_text and html:
        body = 'alternative(text,' + html + ')'
    elif html:
        body = html
    else:
        body = 'text'
    if atts:
        return 'mixed(' + ','.join([body] + ['att'] * atts) + ')'
    return body
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('images without html', (False, False, 2, 0), 'mixed(text,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 2, 0), 'alternative(text,related(html,img,img))'), ('html images and attachment', (False, True, 1, 1), 'mixed(related(html,img),att)'), ('text and attachments', (True, False, 0, 1), 'mixed(text,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 1), 'mixed(alternative(text,related(html,img,img)),att)')], 2: [('images without html', (False, False, 3, 0), 'mixed(text,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 3, 0), 'alternative(text,related(html,img,img,img))'), ('html images and attachment', (False, True, 2, 1), 'mixed(related(html,img,img),att)'), ('text and attachments', (True, False, 0, 2), 'mixed(text,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 2), 'mixed(alternative(text,related(html,img,img)),att,att)')], 3: [('images without html', (False, False, 4, 0), 'mixed(text,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 4, 0), 'alternative(text,related(html,img,img,img,img))'), ('html images and attachment', (False, True, 3, 1), 'mixed(related(html,img,img,img),att)'), ('text and attachments', (True, False, 0, 3), 'mixed(text,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 3), 'mixed(alternative(text,related(html,img,img)),att,att,att)')], 4: [('images without html', (False, False, 5, 0), 'mixed(text,att,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 5, 0), 'alternative(text,related(html,img,img,img,img,img))'), ('html images and attachment', (False, True, 4, 1), 'mixed(related(html,img,img,img,img),att)'), ('text and attachments', (True, False, 0, 4), 'mixed(text,att,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 4), 'mixed(alternative(text,related(html,img,img)),att,att,att,att)')], 5: [('images without html', (False, False, 6, 0), 'mixed(text,att,att,att,att,att,att)'), ('text and html', (True, True, 0, 0), 'alternative(text,html)'), ('text html and images', (True, True, 6, 0), 'alternative(text,related(html,img,img,img,img,img,img))'), ('html images and attachment', (False, True, 5, 1), 'mixed(related(html,img,img,img,img,img),att)'), ('text and attachments', (True, False, 0, 5), 'mixed(text,att,att,att,att,att)'), ('plain text only', (True, False, 0, 0), 'text'), ('everything', (True, True, 2, 5), 'mixed(alternative(text,related(html,img,img)),att,att,att,att,att)')]}
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
images without htmlmixed(text,att,att)mixed(text,att,att)Passed
text and htmlalternative(text,html)alternative(text,html)Passed
text html and imagesalternative(text,related(html,img,img))alternative(text,related(html,img,img))Passed
html images and attachmentmixed(related(html,img),att)mixed(related(html,img),att)Passed
text and attachmentsmixed(text,att)mixed(text,att)Passed
plain text onlytexttextPassed
everythingmixed(alternative(text,related(html,img,img)),att)mixed(alternative(text,related(html,img,img)),att)Passed

SHA-256 / ec74f87d73b4fa1010c8151d39edf169ac8f01d74a67260bb62559e9e13dab15

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

Case digest / 2ede12831ff0c59cf45f3552010f79bea24291dd93f766cc0848c8159b050d9d