← FIELD NOTES
TECHNICALJan 21, 2026·4 MIN READ

The comma that quietly splits your automation in half.

An automated workflow passes every test you write, then breaks the first time a real person types a comma in their address. Here is why, and the three habits that stop it.

B
Brynn
FOUNDER, TRANSFORMATE

From the build log.

We kept hitting the same failure across several different automated workflows — the kind of behind-the-scenes plumbing that takes a form someone fills in and files it neatly into a database. Each one ran clean while we built it. Each one shipped. And a few days later, each one fell over on a record that looked no different from the hundreds that had worked fine.

It took us far too long to spot what those broken records had in common. Every single one of them contained a comma.

Why a comma, of all things

The tool we use to build these workflows has a setting that takes the values from a form — a name, an email, an address — and hands them to the database one at a time, each in its own labelled slot. That is the whole job: keep the values separate and put each one where it belongs.

It turns out the tool quietly treats a comma as a signal to start a new value. So the moment someone types a comma, one value silently becomes two. Now there is an extra piece with nowhere to go, every following value is shunted into the wrong slot, and the database — which was only ever doing what it was told — rejects the whole thing.

The database was behaving perfectly. It was the tool in the middle that miscounted, and never said so.

The cruel part is that the inputs most likely to contain a comma are exactly the ones you would never think to test with. A street address. An email that quotes a sentence. A name written "Surname, First". Your test data is always tidy — short, clean, comma-free — so everything passes. Real people are not tidy. They type the way they talk, commas and all, and that is the moment the thing breaks.

That is the gap between "it works on my machine" and "it is broken for the customer." One piece of punctuation lives in it.

There is no switch to flip — only habits

You cannot turn this behaviour off in a settings menu. You design around it. Three habits cover it:

  1. Clean the text before it reaches that setting. If a field could contain free-typed text, take the commas out first — swap them for something harmless — so each value arrives in one piece.
  2. Never hand the tool a bundle of values all at once. Anything you have squashed into a single blob is a comma minefield. Keep the values separate so each one travels on its own.
  3. Use a clear placeholder for blanks, not nothing at all. An empty value confuses the counting just as badly as an extra comma. Send a deliberate stand-in instead, and translate it back to "empty" at the very end.

None of this is clever. It is just knowing where the floor is thin and choosing to stand somewhere else.

The wider lesson

The thing I take from this is narrower than "test your edge cases" — advice everyone nods along to and nobody actually follows. It is this: when a tool hides the step where it pulls your information apart, you cannot trust how it looks on the surface. You have to know what it does to your data before the database ever sees it.

The very convenience that makes the easy path easy is the same convenience that fails silently on the hard path.

A workflow that passes every test you wrote and breaks on the first comma a real person types is not a flaky workflow. It is a workflow that was only ever tested on data no human would ever produce.

Under the hood

The tool is n8n, and the setting is the queryReplacement field on its Postgres node — the field that binds values into a parameterised query.

The reasonable assumption is that it hands each value to Postgres as one opaque parameter and lets the database sort out the binding. It does not. It tokenises the string on every comma first, then binds the resulting pieces positionally. So the moment a value contains a comma, your parameter count is wrong: one field becomes two, and the query that expected seven parameters now receives eight. That surfaces as there is no parameter $7, or — when the back half of an address lands in the slot meant for an id — invalid input syntax for type uuid.

The three fixes in practice:

  1. Sanitise free-text fields in a Code node before queryReplacement. Strip or escape the commas (swapping for semicolons works) so each value arrives as a single token.
  2. Never pass JSON.stringify(obj) through the field — serialised JSON is commas all the way down. Build the object inside the SQL instead with jsonb_build_object('k1', $1, 'k2', $2, ...), so each value crosses as its own parameter and the commas live in the query text where they belong.
  3. Use a sentinel for nullable fields, not an empty string. An empty string renders as nothing inside an expression and silently desynchronises the parameter parser. Send a literal placeholder such as NULL_, then collapse it back in SQL with NULLIF($1, 'NULL_').

There is no flag that disables the comma-splitting; these three habits are the whole defence.

IF YOU LIKED THIS

Want one of these in your inbox once a month?