Validate CSV
validate_csvValidates CSV text against RFC 4180 and reports ragged rows individually, with both field counts.
Use this before loading a CSV, and whenever a CSV-derived number looks wrong.
Do not attempt this by reading the file, and be aware that loading it successfully proves nothing. The failure that matters is the ragged row: a file where one row has six fields and the header has five loads without complaint almost everywhere — pandas pads or throws depending on the engine, Excel shifts the columns, and split(",") silently mis-assigns every field after the extra one. Nobody notices until a figure is wrong in a report. This reports it as "row 4813 has 6 fields; the header has 5", per row.
The other half is the delimiter. A European CSV is semicolon-separated because the comma is the decimal separator; reading it as comma-separated yields one column of nonsense and no error. The delimiter is sniffed from the header — ignoring quoted regions so their contents cannot vote — and always reported, with a warning when the guess was a close call. Pass delimiter to remove the guess entirely.
Also reports: unterminated quotes (which swallow the rest of the file into one field, which is why one typo can make thousands of rows look ragged), text after a closing quote, stray quotes in unquoted fields, duplicate column names, unnamed columns, column names with invisible leading or trailing whitespace, mixed CRLF/LF line endings, CR-only endings, and a byte order mark — which becomes part of the first column's name, so a lookup for "id" fails against a column that prints identically.
Input: input, the raw CSV text. Optional delimiter (a single character) and hasHeader (default true; pass false and rows are compared against the first row instead, and header checks are skipped). Up to 1,000,000 bytes.
Returns: valid (no errors), parseable (whether a conforming parser would accept it — deliberately separate, because a duplicate key parses fine and still means two different things), a diagnostics array where each entry has a 1-based line and column, a stable rule code, a message, an excerpt showing the offending line with a caret under the column, a fixHint, and blocksParse; plus counts and format-specific stats. Rule codes are stable and safe to branch on; messages are not.
Safety: nothing is resolved, fetched or expanded. External XML entities are reported, never retrieved; alias bombs are detected without being expanded; no schema or DTD is fetched over the network. Payloads are validated in memory and never stored.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes | The raw document text, not a parsed object — the findings are properties of the text. Up to 1,000,000 bytes. | |
| delimiter | No | Field delimiter, as a single character. Omit to sniff it from the header. Pass it when you know it — a semicolon-separated European export read as comma-separated produces one column and no error. | |
| hasHeader | No | Whether the first row names the columns. Default true. Pass false and rows are compared against the first row instead, and header checks are skipped. |