FAILURE MAP
← Case archive

FA-47491 / Delimited text / Open access

An ordinary character fails to leave field-start state · case 01

A structured table violates the declared record or column contract.

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

ROOT CAUSE

The field-start state persists after ordinary text and lets a later quote open a quoted suffix.

VERIFIED REPAIR

Preserve the named invariant at the faulty decision: state = 'bare'

Unsuccessful approach: Treating ordinary text as postquote state rejects legal continuing text.

Case contract

Lex one physical comma record. A quote opens only at field start; doubled quotes decode inside quoted fields; after a closing quote only comma or EOF is legal. CR/LF outside quoted fields reject. Return fields and quote-origin flags; a physical newline inside quoted text remains literal.

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):
    result, buf, state, origin = [], [], 'start', False
    for ch in data:
        if state == 'quoted':
            if ch == '"': state = 'closed'
            else: buf.append(ch)
        elif state == 'closed':
            if ch == '"':
                buf.append('"')
                state = 'quoted'
            elif ch == ',':
                result.append([''.join(buf), origin])
                buf, state, origin = [], 'start', False
            else: return None
        elif ch == ',':
            result.append([''.join(buf), origin])
            buf, state, origin = [], 'start', False
        elif ch == '"':
            if state != 'start': return None
            state, origin = 'quoted', True
        elif ch in '\r\n': return None
        else:
            buf.append(ch)
            state = 'start'
    if state == 'quoted': return None
    result.append([''.join(buf), origin])
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('quoted flags', solve(_vary('"@",a')), _vary([['@', True], ['a', False]]))
check('doubled', solve(_vary('"a""b"')), _vary([['a"b', True]]))
check('triple ending', solve(_vary('"@"""')), _vary([['@"', True]]))
check('empty quoted', solve(_vary('""')), _vary([['', True]]))
check('empty bare', solve(_vary('')), _vary([['', False]]))
check('suffix comma', solve(_vary('"@",')), _vary([['@', True], ['', False]]))
check('bare quote', solve(_vary('a"b')), _vary(None))
check('balanced quote suffix', solve(_vary('a"b"')), _vary(None))
check('junk closing', solve(_vary('"a"x')), _vary(None))
check('space closing', solve(_vary('"a" ')), _vary(None))
check('quoted newlines', solve(_vary('"a\nb"')), _vary([['a\nb', True]]))
check('quoted carriage return', solve(_vary('"a\rb"')), _vary([['a\rb', True]]))
check('unquoted newline', solve(_vary('a\nb')), _vary(None))
check('two quoted', solve(_vary('"a","b"')), _vary([['a', True], ['b', True]]))
check('unterminated', solve(_vary('"a')), _vary(None))
check('plain', solve(_vary('@,z')), _vary([['@', False], ['z', False]]))
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
quoted flags[['cell', True], ['a', False]][['cell', True], ['a', False]]Passed
doubled[['a"b', True]][['a"b', True]]Passed
triple ending[['cell"', True]][['cell"', True]]Passed
empty quoted[['', True]][['', True]]Passed
empty bare[['', False]][['', False]]Passed
suffix comma[['cell', True], ['', False]][['cell', True], ['', False]]Passed
bare quoteNoneNonePassed
balanced quote suffix[['ab', True]]NoneFailed
junk closingNoneNonePassed
space closingNoneNonePassed
quoted newlines[['a\nb', True]][['a\nb', True]]Passed
quoted carriage return[['a\rb', True]][['a\rb', True]]Passed
unquoted newlineNoneNonePassed
two quoted[['a', True], ['b', True]][['a', True], ['b', True]]Passed
unterminatedNoneNonePassed
plain[['cell', False], ['z', False]][['cell', False], ['z', False]]Passed

SHA-256 / 8e2c5c00de9d77af934e46484991fa98e14ef9b8957c6db4b81938c6421091ed

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):
    result, buf, state, origin = [], [], 'start', False
    for ch in data:
        if state == 'quoted':
            if ch == '"': state = 'closed'
            else: buf.append(ch)
        elif state == 'closed':
            if ch == '"':
                buf.append('"')
                state = 'quoted'
            elif ch == ',':
                result.append([''.join(buf), origin])
                buf, state, origin = [], 'start', False
            else: return None
        elif ch == ',':
            result.append([''.join(buf), origin])
            buf, state, origin = [], 'start', False
        elif ch == '"':
            if state != 'start': return None
            state, origin = 'quoted', True
        elif ch in '\r\n': return None
        else:
            buf.append(ch)
            state = 'closed'
    if state == 'quoted': return None
    result.append([''.join(buf), origin])
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('quoted flags', solve(_vary('"@",a')), _vary([['@', True], ['a', False]]))
check('doubled', solve(_vary('"a""b"')), _vary([['a"b', True]]))
check('triple ending', solve(_vary('"@"""')), _vary([['@"', True]]))
check('empty quoted', solve(_vary('""')), _vary([['', True]]))
check('empty bare', solve(_vary('')), _vary([['', False]]))
check('suffix comma', solve(_vary('"@",')), _vary([['@', True], ['', False]]))
check('bare quote', solve(_vary('a"b')), _vary(None))
check('balanced quote suffix', solve(_vary('a"b"')), _vary(None))
check('junk closing', solve(_vary('"a"x')), _vary(None))
check('space closing', solve(_vary('"a" ')), _vary(None))
check('quoted newlines', solve(_vary('"a\nb"')), _vary([['a\nb', True]]))
check('quoted carriage return', solve(_vary('"a\rb"')), _vary([['a\rb', True]]))
check('unquoted newline', solve(_vary('a\nb')), _vary(None))
check('two quoted', solve(_vary('"a","b"')), _vary([['a', True], ['b', True]]))
check('unterminated', solve(_vary('"a')), _vary(None))
check('plain', solve(_vary('@,z')), _vary([['@', False], ['z', False]]))
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
quoted flags[['cell', True], ['a', False]][['cell', True], ['a', False]]Passed
doubled[['a"b', True]][['a"b', True]]Passed
triple ending[['cell"', True]][['cell"', True]]Passed
empty quoted[['', True]][['', True]]Passed
empty bare[['', False]][['', False]]Passed
suffix comma[['cell', True], ['', False]][['cell', True], ['', False]]Passed
bare quoteNoneNonePassed
balanced quote suffix[['a"b', False]]NoneFailed
junk closingNoneNonePassed
space closingNoneNonePassed
quoted newlines[['a\nb', True]][['a\nb', True]]Passed
quoted carriage return[['a\rb', True]][['a\rb', True]]Passed
unquoted newlineNoneNonePassed
two quoted[['a', True], ['b', True]][['a', True], ['b', True]]Passed
unterminatedNoneNonePassed
plainNone[['cell', False], ['z', False]]Failed

SHA-256 / 23f58c7438b11611623bf159c28bbd08f8cc73e4a566129535bc7e1b48082c06

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):
    result, buf, state, origin = [], [], 'start', False
    for ch in data:
        if state == 'quoted':
            if ch == '"': state = 'closed'
            else: buf.append(ch)
        elif state == 'closed':
            if ch == '"':
                buf.append('"')
                state = 'quoted'
            elif ch == ',':
                result.append([''.join(buf), origin])
                buf, state, origin = [], 'start', False
            else: return None
        elif ch == ',':
            result.append([''.join(buf), origin])
            buf, state, origin = [], 'start', False
        elif ch == '"':
            if state != 'start': return None
            state, origin = 'quoted', True
        elif ch in '\r\n': return None
        else:
            buf.append(ch)
            state = 'bare'
    if state == 'quoted': return None
    result.append([''.join(buf), origin])
    return result
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('quoted flags', solve(_vary('"@",a')), _vary([['@', True], ['a', False]]))
check('doubled', solve(_vary('"a""b"')), _vary([['a"b', True]]))
check('triple ending', solve(_vary('"@"""')), _vary([['@"', True]]))
check('empty quoted', solve(_vary('""')), _vary([['', True]]))
check('empty bare', solve(_vary('')), _vary([['', False]]))
check('suffix comma', solve(_vary('"@",')), _vary([['@', True], ['', False]]))
check('bare quote', solve(_vary('a"b')), _vary(None))
check('balanced quote suffix', solve(_vary('a"b"')), _vary(None))
check('junk closing', solve(_vary('"a"x')), _vary(None))
check('space closing', solve(_vary('"a" ')), _vary(None))
check('quoted newlines', solve(_vary('"a\nb"')), _vary([['a\nb', True]]))
check('quoted carriage return', solve(_vary('"a\rb"')), _vary([['a\rb', True]]))
check('unquoted newline', solve(_vary('a\nb')), _vary(None))
check('two quoted', solve(_vary('"a","b"')), _vary([['a', True], ['b', True]]))
check('unterminated', solve(_vary('"a')), _vary(None))
check('plain', solve(_vary('@,z')), _vary([['@', False], ['z', False]]))
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
quoted flags[['cell', True], ['a', False]][['cell', True], ['a', False]]Passed
doubled[['a"b', True]][['a"b', True]]Passed
triple ending[['cell"', True]][['cell"', True]]Passed
empty quoted[['', True]][['', True]]Passed
empty bare[['', False]][['', False]]Passed
suffix comma[['cell', True], ['', False]][['cell', True], ['', False]]Passed
bare quoteNoneNonePassed
balanced quote suffixNoneNonePassed
junk closingNoneNonePassed
space closingNoneNonePassed
quoted newlines[['a\nb', True]][['a\nb', True]]Passed
quoted carriage return[['a\rb', True]][['a\rb', True]]Passed
unquoted newlineNoneNonePassed
two quoted[['a', True], ['b', True]][['a', True], ['b', True]]Passed
unterminatedNoneNonePassed
plain[['cell', False], ['z', False]][['cell', False], ['z', False]]Passed

SHA-256 / bac48864035b7b80055290c2dab4772ec827a8f19a1edf5dceabcc1205a99283

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

Case digest / 4c599236d72e2d9e9ee13009a74bad381a1f59f8e191e534e916fc29903d14d2