FLOWLOGIC
module /files-and-documents

unit U22 of 5

CSV is a trap

quoting, delimiters, BOM, everything is text

CSV looks like the simplest format in the world and is the one that quietly breaks most imports. There is no single specification, so every producer makes different choices: comma or semicolon, quoted fields or not, CRLF or LF, and whether a leading byte-order mark is included. A parser that splits on commas works until the first row containing a company name with a comma in it, at which point every column after that shifts by one — for that row only.

Use a real CSV parser, never `split(",")`. A proper parser understands quoted fields, escaped quotes inside them, and newlines *within* a quoted value, all of which occur in real exports of addresses and notes. Detect the delimiter rather than assuming it: European locales export semicolon-separated files because the comma is their decimal separator. Strip the byte-order mark if present, or your first column header arrives as `id` and every lookup on `id` silently misses.

Where it breaks: trusting the types. Every CSV value is text. A postcode of `01234` becomes `1234` if you coerce it to a number, phone numbers lose their leading `+`, and a spreadsheet somewhere has already turned a product code like `1-2` into a date. Read every column as a string, convert deliberately, and treat the file as data that has probably been through Excel.

worked example

The row that defeats a naive split — and what a real parser does with it.

id,company,notes,postcode
1,"Acme, Ltd","Said ""call back"" on Friday",01234

split(',') gives 6 fields for a 4-column row:
  ['1', '"Acme', ' Ltd"', '"Said ""call back""', ' on Friday"', '01234']
  -> every column after `company` is shifted, for this row only

a real parser gives 4:
  id=1
  company=Acme, Ltd                    quoted comma
  notes=Said "call back" on Friday     escaped quotes
  postcode=01234                       STRING - Number() makes it 1234

also present in real exports and invisible in a text editor:
  \uFEFF byte-order mark before `id`   -> row['id'] is undefined
  CRLF line endings                    -> a trailing \r on the last column

field checklist

common failure — One comma shifted every column

An import split rows on commas. It ran cleanly for months until a customer named "Acme, Ltd" appeared: that row gained a column, so its postcode landed in the phone field and its notes in the postcode field — for that record only, with no error. Use a parser that understands quoting, and validate each row's column count against the header before mapping anything.

check your understanding

A CSV import from a European client fails in ways your test file never showed. Select everything a real-world parser has to handle.

  • select every one that applies — partial answers are marked wrong

next unit opens once this is passed

sandbox validation

The check above confirms you followed the unit. Marking the module COMPLETED takes more: build the automation in your own engine and submit the exported flow and its run evidence, signed, to your unique validation URL. See the module page for that spec.