csv.Error

The csv module's own exception — tracebacks call it _csv.Error, after the C module that defines it. It derives directly from Exception, so except ValueError does not catch it.

InheritsBaseException›Exception›Error
csv exceptionPython 2.3+Live demo
csv.Error(*args*args — Like any Exception: the message (str(e) is the first argument when there is one).type: any · default: null)
Raised by
reader iteration, writerow, get_dialect / unregister_dialect, Sniffer.sniff
Message
field larger than field limit (131072)
Quick fix
except csv.Error as e: report e with reader.line_num
Watch out
bad settings (delimiter='::') are TypeError / ValueError, not csv.Error

Demo

Live evaluation
Read your text (\n = line break) with strict=True, uncaught: malformed input ends in a csv.Error.
Try:
Inputs
textstrCSV text, \n = line break
Code
import csv, io
text = 'id,note\\n1,"never closed'.replace('\\n', '\n')
list(csv.reader(io.StringIO(text, newline=''), strict=True))
Uncaught exception
_csv.Error: unexpected end of data

The traceback shows _csv.Error: csv.Error is the same class, re-exported by Lib/csv.py. line_num is the number of input lines consumed when the error happened — for an unclosed quote that is the last line of the input, since the reader kept looking for the closing quote.

Parameters

NameTypeRequiredDescription
argsanynoLike any Exception: the message (str(e) is the first argument when there is one).

Attributes

AttributeTypeMeaning
argstupleThe constructor arguments; for errors raised by csv itself, a 1-tuple with the message.

Common patterns

Report the bad line
reader.line_num points at the line where parsing stopped.
import csv
with open('data.csv', newline='', encoding='utf-8') as f:
    rows = csv.reader(f, strict=True)
    try:
        data = list(rows)
    except csv.Error as e:
        raise SystemExit(f'data.csv, line {rows.line_num}: {e}')
Skip bad rows
Catch per row and continue — the reader resets its state for the next row.
import csv
good = []
rows = csv.reader(lines, strict=True)
while True:
    try:
        row = next(rows)
    except StopIteration:
        break
    except csv.Error:
        continue
    good.append(row)

Examples

1. Traceback name
import csv list(csv.reader(['a,"b'], strict=True))
Returns
_csv.Error: unexpected end of data
2. Same class, two names
import csv, _csv csv.Error is _csv.Error
Returns
True
3. Directly under Exception
import csv [c.__name__ for c in csv.Error.__mro__]
Returns
['Error', 'Exception', 'BaseException', 'object']
4. Writer errors too
import csv, io csv.writer(io.StringIO(), quoting=csv.QUOTE_NONE).writerow(['a,b'])
Returns
_csv.Error: need to escape, but no escapechar set
5. A single empty field under QUOTE_NONE
import csv, io csv.writer(io.StringIO(), quoting=csv.QUOTE_NONE).writerow([''])
Returns
_csv.Error: single empty field record must be quoted
6. Catch and inspect
import csv try: csv.get_dialect('nope') except csv.Error as e: info = (type(e).__name__, e.args) info
Returns
('Error', ('unknown dialect',))

Pitfalls

1. Catching ValueError
csv.Error is not a ValueError subclass, so a handler for ValueError lets it through.
except ValueError
import csv
try:
    rows = list(csv.reader(['a,"b'], strict=True))
except ValueError:
    rows = []
rows
_csv.Error: unexpected end of data
except csv.Error
import csv
try:
    rows = list(csv.reader(['a,"b'], strict=True))
except csv.Error:
    rows = []
rows
[]
2. Expecting csv.Error for bad settings
Invalid dialect parameters are checked like function arguments: TypeError or ValueError, not csv.Error.
except csv.Error
import csv
try:
    csv.reader([], delimiter='::')
except csv.Error:
    msg = 'caught'
TypeError: "delimiter" must be a 1-character string
except (TypeError, ValueError)
import csv
try:
    csv.reader([], delimiter='::')
except (TypeError, ValueError) as e:
    msg = str(e)
msg
'"delimiter" must be a 1-character string'

When to use

Use it
  • Around reading user-supplied CSV, together with strict=True
  • To report the line number of malformed input
Reach for something else
  • Catching it for invalid dialect settings — those are TypeError/ValueError
  • Catching it for type conversion with QUOTE_NONNUMERIC — that is ValueError

Notes

CPython impl
Modules/_csv.c — created in csv_exec as _csv.Error with Exception as base; Lib/csv.py imports it as csv.Error. Raised as Error(message), no extra attributes
Messages
Reader: ',' expected after '"' · unexpected end of data · field larger than field limit (N) · new-line character seen in unquoted field … · iterator should return strings, not … Writer: need to escape, but no escapechar set · single empty field record must be quoted · iterable expected, not … Registry: unknown dialect. Sniffer: Could not determine delimiter

FAQ

The class is defined in the C module _csv and re-exported by csv. They are the same object; catch it as csv.Error.