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.
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
| Name | Type | Required | Description |
|---|---|---|---|
| args | any | no | Like any Exception: the message (str(e) is the first argument when there is one). |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| args | tuple | The 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 data2. Same class, two names
import csv, _csv
csv.Error is _csv.Error
Returns
True3. 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 set5. 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 quoted6. 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.