FAILURE MAP
← Case archive

FA-47661 / Delimited text / Open access

The CSV writer leaves trim-sensitive edge spaces unquoted · case 01

A structured table violates the declared record or column contract.

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

ROOT CAUSE

Minimal quoting ignores the consumer contract that trims bare edge spaces.

VERIFIED REPAIR

Preserve the named invariant at the faulty decision: or value != value.strip(' ')

Unsuccessful approach: Protecting only leading spaces misses a trailing-space value.

Case contract

Emit typed table cells as one comma row ending CRLF. None is bare NULL; strings equal NULL or empty must be quoted. Booleans are bare true/false, integers bare decimal. Other strings are quoted if they contain comma, quote, newline, CR, leading/trailing space, or begin # (comment protection). Double embedded quotes. Preserve Unicode and cell order.

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):
    out = []
    for value in data:
        if value is None: field = 'NULL'
        elif isinstance(value, bool): field = 'true' if value else 'false'
        elif isinstance(value, int): field = str(value)
        else:
            quote = value in ('NULL', '') or any(c in value for c in ',"\r\n')  or value.startswith('#')
            field = value.replace('"', '""')
            if quote: field = '"' + field + '"'
        out.append(field)
    return ','.join(out) + '\r\n'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('typed', solve(_vary(['@', None, True, False, 12])), _vary('@,NULL,true,false,12\r\n'))
check('null string', solve(_vary(['NULL', ''])), _vary('"NULL",""\r\n'))
check('comment', solve(_vary(['#@'])), _vary('"#@"\r\n'))
check('spaces', solve(_vary([' @ ', 'x'])), _vary('" @ ",x\r\n'))
check('escape', solve(_vary(['a"b'])), _vary('"a""b"\r\n'))
check('crlf', solve(_vary(['x\r\ny'])), _vary('"x\r\ny"\r\n'))
check('normal', solve(_vary(['@', 'β'])), _vary('@,β\r\n'))
check('empty row', solve(_vary([])), _vary('\r\n'))
check('negative', solve(_vary([-12])), _vary('-12\r\n'))
check('single space', solve(_vary([' '])), _vary('" "\r\n'))
check('trailing space', solve(_vary(['@ '])), _vary('"@ "\r\n'))
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
typedcell,NULL,true,false,12 cell,NULL,true,false,12 Passed
null string"NULL","" "NULL","" Passed
comment"#cell" "#cell" Passed
spaces cell ,x " cell ",x Failed
escape"a""b" "a""b" Passed
crlf"x y" "x y" Passed
normalcell,β cell,β Passed
empty row Passed
negative-12 -12 Passed
single space " " Failed
trailing spacecell "cell " Failed

SHA-256 / 08eb212695c6f2b3c1d1ba3d157255a2e9c3ce95abeffe9ebc345cee3af30c4b

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):
    out = []
    for value in data:
        if value is None: field = 'NULL'
        elif isinstance(value, bool): field = 'true' if value else 'false'
        elif isinstance(value, int): field = str(value)
        else:
            quote = value in ('NULL', '') or any(c in value for c in ',"\r\n') or value.startswith(' ') or value.startswith('#')
            field = value.replace('"', '""')
            if quote: field = '"' + field + '"'
        out.append(field)
    return ','.join(out) + '\r\n'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('typed', solve(_vary(['@', None, True, False, 12])), _vary('@,NULL,true,false,12\r\n'))
check('null string', solve(_vary(['NULL', ''])), _vary('"NULL",""\r\n'))
check('comment', solve(_vary(['#@'])), _vary('"#@"\r\n'))
check('spaces', solve(_vary([' @ ', 'x'])), _vary('" @ ",x\r\n'))
check('escape', solve(_vary(['a"b'])), _vary('"a""b"\r\n'))
check('crlf', solve(_vary(['x\r\ny'])), _vary('"x\r\ny"\r\n'))
check('normal', solve(_vary(['@', 'β'])), _vary('@,β\r\n'))
check('empty row', solve(_vary([])), _vary('\r\n'))
check('negative', solve(_vary([-12])), _vary('-12\r\n'))
check('single space', solve(_vary([' '])), _vary('" "\r\n'))
check('trailing space', solve(_vary(['@ '])), _vary('"@ "\r\n'))
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
typedcell,NULL,true,false,12 cell,NULL,true,false,12 Passed
null string"NULL","" "NULL","" Passed
comment"#cell" "#cell" Passed
spaces" cell ",x " cell ",x Passed
escape"a""b" "a""b" Passed
crlf"x y" "x y" Passed
normalcell,β cell,β Passed
empty row Passed
negative-12 -12 Passed
single space" " " " Passed
trailing spacecell "cell " Failed

SHA-256 / 53f9383f651e6b1f2c728acf5ddbed51a20d2f544fcc85de0392c752fc4bd268

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):
    out = []
    for value in data:
        if value is None: field = 'NULL'
        elif isinstance(value, bool): field = 'true' if value else 'false'
        elif isinstance(value, int): field = str(value)
        else:
            quote = value in ('NULL', '') or any(c in value for c in ',"\r\n') or value != value.strip(' ') or value.startswith('#')
            field = value.replace('"', '""')
            if quote: field = '"' + field + '"'
        out.append(field)
    return ','.join(out) + '\r\n'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('typed', solve(_vary(['@', None, True, False, 12])), _vary('@,NULL,true,false,12\r\n'))
check('null string', solve(_vary(['NULL', ''])), _vary('"NULL",""\r\n'))
check('comment', solve(_vary(['#@'])), _vary('"#@"\r\n'))
check('spaces', solve(_vary([' @ ', 'x'])), _vary('" @ ",x\r\n'))
check('escape', solve(_vary(['a"b'])), _vary('"a""b"\r\n'))
check('crlf', solve(_vary(['x\r\ny'])), _vary('"x\r\ny"\r\n'))
check('normal', solve(_vary(['@', 'β'])), _vary('@,β\r\n'))
check('empty row', solve(_vary([])), _vary('\r\n'))
check('negative', solve(_vary([-12])), _vary('-12\r\n'))
check('single space', solve(_vary([' '])), _vary('" "\r\n'))
check('trailing space', solve(_vary(['@ '])), _vary('"@ "\r\n'))
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
typedcell,NULL,true,false,12 cell,NULL,true,false,12 Passed
null string"NULL","" "NULL","" Passed
comment"#cell" "#cell" Passed
spaces" cell ",x " cell ",x Passed
escape"a""b" "a""b" Passed
crlf"x y" "x y" Passed
normalcell,β cell,β Passed
empty row Passed
negative-12 -12 Passed
single space" " " " Passed
trailing space"cell " "cell " Passed

SHA-256 / 01dab3c6df4f14a2de881e543fd7f557862fb045b3894b8344acc59adc9432de

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

Case digest / f3330032d9fd81a8ca8862624fa7d75a2ac54d4269ce87573d61ac8c9cdfc368