FA-48601 / Delimited text / Open access
Missing union columns are filled with empty strings · case 01
A structured table violates the declared record or column contract.
ROOT CAUSE
Missing union columns are filled with empty strings.
VERIFIED REPAIR
Preserve the named invariant at the faulty decision: mapping.get(name)
Unsuccessful approach: The alternate implementation still violates the same declared invariant: missing union columns are filled with empty strings.
Case contract
Combine a list of tables, each {header:[names], rows:[[cells]]}. Output header is the first-seen union of names, preserving first-seen order. Duplicate names within one input header and row-width mismatches reject. Missing columns in a table become null; explicit empty values remain empty. Return {header,rows}.
Why this case matters
Delimited interchange needs explicit framing, schema and field semantics at ingestion and emission boundaries.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
def _vary(value):
if value == '@END': return 3 + 4*N
if isinstance(value, str): return value.replace('@', 'cell' * N)
if isinstance(value, list): return [_vary(x) for x in value]
if isinstance(value, dict): return {_vary(k): _vary(v) for k,v in value.items()}
return value
N = 1
observations = []
def solve(data):
header=[]
for table in data:
if len(set(table['header']))!=len(table['header']): return None
for name in table['header']:
if name not in header: header.append(name)
out=[]
for table in data:
for row in table['rows']:
if len(row)!=len(table['header']): return None
mapping=dict(zip(table['header'],row))
out.append([mapping.get(name,'') for name in header])
return {'header':header,'rows':out}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('union', solve(_vary([{'header': ['b', 'a'], 'rows': [['@', 'x']]}, {'header': ['a', 'c'], 'rows': [['y', 'z']]}])), _vary({'header': ['b', 'a', 'c'], 'rows': [['@', 'x', None], [None, 'y', 'z']]}))
check('reordered', solve(_vary([{'header': ['a', 'b'], 'rows': [['@', 'x']]}, {'header': ['b', 'a'], 'rows': [['z', 'y']]}])), _vary({'header': ['a', 'b'], 'rows': [['@', 'x'], ['y', 'z']]}))
check('duplicate', solve(_vary([{'header': ['a', 'a'], 'rows': []}])), _vary(None))
check('ragged', solve(_vary([{'header': ['a', 'b'], 'rows': [['@']]}])), _vary(None))
check('explicit empty', solve(_vary([{'header': ['a'], 'rows': [['']]}, {'header': ['b'], 'rows': [['@']]}])), _vary({'header': ['a', 'b'], 'rows': [['', None], [None, '@']]}))
check('empty', solve(_vary([])), _vary({'header': [], 'rows': []}))
check('header only', solve(_vary([{'header': ['@'], 'rows': []}])), _vary({'header': ['@'], 'rows': []}))
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| union | {'header': ['b', 'a', 'c'], 'rows': [['cell', 'x', ''], ['', 'y', 'z']]} | {'header': ['b', 'a', 'c'], 'rows': [['cell', 'x', None], [None, 'y', 'z']]} | Failed |
| reordered | {'header': ['a', 'b'], 'rows': [['cell', 'x'], ['y', 'z']]} | {'header': ['a', 'b'], 'rows': [['cell', 'x'], ['y', 'z']]} | Passed |
| duplicate | None | None | Passed |
| ragged | None | None | Passed |
| explicit empty | {'header': ['a', 'b'], 'rows': [['', ''], ['', 'cell']]} | {'header': ['a', 'b'], 'rows': [['', None], [None, 'cell']]} | Failed |
| empty | {'header': [], 'rows': []} | {'header': [], 'rows': []} | Passed |
| header only | {'header': ['cell'], 'rows': []} | {'header': ['cell'], 'rows': []} | Passed |
SHA-256 / b6ae099599133da80ba8db8d7e1179e5d8084b50d97ea4a587ecda751bd52b71
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
def _vary(value):
if value == '@END': return 3 + 4*N
if isinstance(value, str): return value.replace('@', 'cell' * N)
if isinstance(value, list): return [_vary(x) for x in value]
if isinstance(value, dict): return {_vary(k): _vary(v) for k,v in value.items()}
return value
N = 1
observations = []
def solve(data):
header=[]
for table in data:
if len(set(table['header']))!=len(table['header']): return None
for name in table['header']:
if name not in header: header.append(name)
out=[]
for table in data:
for row in table['rows']:
if len(row)!=len(table['header']): return None
mapping=dict(zip(table['header'],row))
out.append([mapping.get(name,0) for name in header])
return {'header':header,'rows':out}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('union', solve(_vary([{'header': ['b', 'a'], 'rows': [['@', 'x']]}, {'header': ['a', 'c'], 'rows': [['y', 'z']]}])), _vary({'header': ['b', 'a', 'c'], 'rows': [['@', 'x', None], [None, 'y', 'z']]}))
check('reordered', solve(_vary([{'header': ['a', 'b'], 'rows': [['@', 'x']]}, {'header': ['b', 'a'], 'rows': [['z', 'y']]}])), _vary({'header': ['a', 'b'], 'rows': [['@', 'x'], ['y', 'z']]}))
check('duplicate', solve(_vary([{'header': ['a', 'a'], 'rows': []}])), _vary(None))
check('ragged', solve(_vary([{'header': ['a', 'b'], 'rows': [['@']]}])), _vary(None))
check('explicit empty', solve(_vary([{'header': ['a'], 'rows': [['']]}, {'header': ['b'], 'rows': [['@']]}])), _vary({'header': ['a', 'b'], 'rows': [['', None], [None, '@']]}))
check('empty', solve(_vary([])), _vary({'header': [], 'rows': []}))
check('header only', solve(_vary([{'header': ['@'], 'rows': []}])), _vary({'header': ['@'], 'rows': []}))
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| union | {'header': ['b', 'a', 'c'], 'rows': [['cell', 'x', 0], [0, 'y', 'z']]} | {'header': ['b', 'a', 'c'], 'rows': [['cell', 'x', None], [None, 'y', 'z']]} | Failed |
| reordered | {'header': ['a', 'b'], 'rows': [['cell', 'x'], ['y', 'z']]} | {'header': ['a', 'b'], 'rows': [['cell', 'x'], ['y', 'z']]} | Passed |
| duplicate | None | None | Passed |
| ragged | None | None | Passed |
| explicit empty | {'header': ['a', 'b'], 'rows': [['', 0], [0, 'cell']]} | {'header': ['a', 'b'], 'rows': [['', None], [None, 'cell']]} | Failed |
| empty | {'header': [], 'rows': []} | {'header': [], 'rows': []} | Passed |
| header only | {'header': ['cell'], 'rows': []} | {'header': ['cell'], 'rows': []} | Passed |
SHA-256 / 8e6c396291addaa93d386313313dde0ada2654e4ab65a1ec9f86ff862fde6adf
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
def _vary(value):
if value == '@END': return 3 + 4*N
if isinstance(value, str): return value.replace('@', 'cell' * N)
if isinstance(value, list): return [_vary(x) for x in value]
if isinstance(value, dict): return {_vary(k): _vary(v) for k,v in value.items()}
return value
N = 1
observations = []
def solve(data):
header=[]
for table in data:
if len(set(table['header']))!=len(table['header']): return None
for name in table['header']:
if name not in header: header.append(name)
out=[]
for table in data:
for row in table['rows']:
if len(row)!=len(table['header']): return None
mapping=dict(zip(table['header'],row))
out.append([mapping.get(name) for name in header])
return {'header':header,'rows':out}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('union', solve(_vary([{'header': ['b', 'a'], 'rows': [['@', 'x']]}, {'header': ['a', 'c'], 'rows': [['y', 'z']]}])), _vary({'header': ['b', 'a', 'c'], 'rows': [['@', 'x', None], [None, 'y', 'z']]}))
check('reordered', solve(_vary([{'header': ['a', 'b'], 'rows': [['@', 'x']]}, {'header': ['b', 'a'], 'rows': [['z', 'y']]}])), _vary({'header': ['a', 'b'], 'rows': [['@', 'x'], ['y', 'z']]}))
check('duplicate', solve(_vary([{'header': ['a', 'a'], 'rows': []}])), _vary(None))
check('ragged', solve(_vary([{'header': ['a', 'b'], 'rows': [['@']]}])), _vary(None))
check('explicit empty', solve(_vary([{'header': ['a'], 'rows': [['']]}, {'header': ['b'], 'rows': [['@']]}])), _vary({'header': ['a', 'b'], 'rows': [['', None], [None, '@']]}))
check('empty', solve(_vary([])), _vary({'header': [], 'rows': []}))
check('header only', solve(_vary([{'header': ['@'], 'rows': []}])), _vary({'header': ['@'], 'rows': []}))
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| union | {'header': ['b', 'a', 'c'], 'rows': [['cell', 'x', None], [None, 'y', 'z']]} | {'header': ['b', 'a', 'c'], 'rows': [['cell', 'x', None], [None, 'y', 'z']]} | Passed |
| reordered | {'header': ['a', 'b'], 'rows': [['cell', 'x'], ['y', 'z']]} | {'header': ['a', 'b'], 'rows': [['cell', 'x'], ['y', 'z']]} | Passed |
| duplicate | None | None | Passed |
| ragged | None | None | Passed |
| explicit empty | {'header': ['a', 'b'], 'rows': [['', None], [None, 'cell']]} | {'header': ['a', 'b'], 'rows': [['', None], [None, 'cell']]} | Passed |
| empty | {'header': [], 'rows': []} | {'header': [], 'rows': []} | Passed |
| header only | {'header': ['cell'], 'rows': []} | {'header': ['cell'], 'rows': []} | Passed |
SHA-256 / e4872d3961c87210a1ee583e451be27d5b2d67f57f854db1139e988716afa70f
Verification & scope
Deterministic bounded in-memory model. No claim of complete CSV or external format conformance. 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:44:52.151131+00:00.
Case digest / fc2d7a9848d1a69ecf9e4af7e60f280519871915a05bbade691c139f89aa23f5