FAILURE MAP
← Case archive

FA-47511 / Delimited text / Open access

A CR consumes an arbitrary next character as LF · case 01

A structured table violates the declared record or column contract.

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

ROOT CAUSE

The pending-CR transition accepts any character as a record terminator.

VERIFIED REPAIR

Preserve the named invariant at the faulty decision: if ch != '\n': return None

Unsuccessful approach: Rejecting only another CR still consumes ordinary text after CR.

Case contract

Frame raw TSV records from arbitrary string chunks using CRLF only. Bare CR and bare LF are invalid. A trailing nonterminated record is allowed; a final CR is invalid. Return records without terminators, retaining empty records.

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):
    rows, buf, pending = [], [], False
    for chunk in data:
        for ch in chunk:
            if pending:
                if False: return None
                rows.append(''.join(buf))
                buf, pending = [], False
            elif ch == '\r': pending = True
            elif ch == '\n': return None
            else: buf.append(ch)
    if pending: return None
    if buf: rows.append(''.join(buf))
    return rows
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('split terminator', solve(_vary(['@\r', '\nZ\r', '\n'])), _vary(['@', 'Z']))
check('whole', solve(_vary(['@\tA\r\nB'])), _vary(['@\tA', 'B']))
check('empty records', solve(_vary(['\r\n\r\n'])), _vary(['', '']))
check('empty chunks', solve(_vary(['', '@', '', '\r', '', '\n', ''])), _vary(['@']))
check('trailing CR', solve(_vary(['@\r'])), _vary(None))
check('bare LF', solve(_vary(['@\n'])), _vary(None))
check('bad CR', solve(_vary(['@\rZ'])), _vary(None))
check('no data', solve(_vary([])), _vary([]))
check('trailing unframed', solve(_vary(['@'])), _vary(['@']))
check('three chunks', solve(_vary(['@\r', '\n', 'X'])), _vary(['@', 'X']))
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
split terminator['cell', 'Z']['cell', 'Z']Passed
whole['cell\tA', 'B']['cell\tA', 'B']Passed
empty records['', '']['', '']Passed
empty chunks['cell']['cell']Passed
trailing CRNoneNonePassed
bare LFNoneNonePassed
bad CR['cell']NoneFailed
no data[][]Passed
trailing unframed['cell']['cell']Passed
three chunks['cell', 'X']['cell', 'X']Passed

SHA-256 / c1c25e7e3947821f3991f12b1a621f80940c45bdfb9fb624eb6c9ad89a2d0173

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):
    rows, buf, pending = [], [], False
    for chunk in data:
        for ch in chunk:
            if pending:
                if ch == '\r': return None
                rows.append(''.join(buf))
                buf, pending = [], False
            elif ch == '\r': pending = True
            elif ch == '\n': return None
            else: buf.append(ch)
    if pending: return None
    if buf: rows.append(''.join(buf))
    return rows
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('split terminator', solve(_vary(['@\r', '\nZ\r', '\n'])), _vary(['@', 'Z']))
check('whole', solve(_vary(['@\tA\r\nB'])), _vary(['@\tA', 'B']))
check('empty records', solve(_vary(['\r\n\r\n'])), _vary(['', '']))
check('empty chunks', solve(_vary(['', '@', '', '\r', '', '\n', ''])), _vary(['@']))
check('trailing CR', solve(_vary(['@\r'])), _vary(None))
check('bare LF', solve(_vary(['@\n'])), _vary(None))
check('bad CR', solve(_vary(['@\rZ'])), _vary(None))
check('no data', solve(_vary([])), _vary([]))
check('trailing unframed', solve(_vary(['@'])), _vary(['@']))
check('three chunks', solve(_vary(['@\r', '\n', 'X'])), _vary(['@', 'X']))
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
split terminator['cell', 'Z']['cell', 'Z']Passed
whole['cell\tA', 'B']['cell\tA', 'B']Passed
empty records['', '']['', '']Passed
empty chunks['cell']['cell']Passed
trailing CRNoneNonePassed
bare LFNoneNonePassed
bad CR['cell']NoneFailed
no data[][]Passed
trailing unframed['cell']['cell']Passed
three chunks['cell', 'X']['cell', 'X']Passed

SHA-256 / a05db0bd640593bccc549a07b14f8a7e493d44f4f35f91d517a11d70fb58f075

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):
    rows, buf, pending = [], [], False
    for chunk in data:
        for ch in chunk:
            if pending:
                if ch != '\n': return None
                rows.append(''.join(buf))
                buf, pending = [], False
            elif ch == '\r': pending = True
            elif ch == '\n': return None
            else: buf.append(ch)
    if pending: return None
    if buf: rows.append(''.join(buf))
    return rows
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('split terminator', solve(_vary(['@\r', '\nZ\r', '\n'])), _vary(['@', 'Z']))
check('whole', solve(_vary(['@\tA\r\nB'])), _vary(['@\tA', 'B']))
check('empty records', solve(_vary(['\r\n\r\n'])), _vary(['', '']))
check('empty chunks', solve(_vary(['', '@', '', '\r', '', '\n', ''])), _vary(['@']))
check('trailing CR', solve(_vary(['@\r'])), _vary(None))
check('bare LF', solve(_vary(['@\n'])), _vary(None))
check('bad CR', solve(_vary(['@\rZ'])), _vary(None))
check('no data', solve(_vary([])), _vary([]))
check('trailing unframed', solve(_vary(['@'])), _vary(['@']))
check('three chunks', solve(_vary(['@\r', '\n', 'X'])), _vary(['@', 'X']))
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
split terminator['cell', 'Z']['cell', 'Z']Passed
whole['cell\tA', 'B']['cell\tA', 'B']Passed
empty records['', '']['', '']Passed
empty chunks['cell']['cell']Passed
trailing CRNoneNonePassed
bare LFNoneNonePassed
bad CRNoneNonePassed
no data[][]Passed
trailing unframed['cell']['cell']Passed
three chunks['cell', 'X']['cell', 'X']Passed

SHA-256 / f495bf941e395e1a4d39a9c3aa637de71fe7a5e1e9f5955fd1bc41eb65d05334

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

Case digest / b63ba010481a3bac42d3f15d55b2c9067461c24c11f3a90f2bf6ff9206bd0f27