Second scenario, running on sample data

Repeat fields

The first scenario handles a form where every field is filled in once. This one handles the part of JetFormBuilder that breaks a straightforward field mapping: a repeat field, where an applicant adds as many rows as they want. Those rows do not arrive the way the other fields do, and what you do about that decides whether they land in Airtable or quietly go missing.

Everything on this page was measured against a live Make webhook rather than described. The submissions below were posted at it in exactly the shape JetFormBuilder posts them, and the values shown are what came back. ← the first scenario

The short version

A repeat field arrives as indexed keys, not as a single field. Make turns those into a proper list, so the rows are there and usable. Two things about that list will break an intake form in production, and neither shows up while you are testing with a filled-in submission: an applicant who adds no rows at all sends something that stops the whole run, and a half-filled row writes a blank preference that looks real. Both are handled below, and both are shown failing and then not failing.

Wire

What the webhook actually receives

JetFormBuilder Call Webhook · application/x-www-form-urlencoded

JetFormBuilder posts the submission as form data rather than JSON. A repeat field named dealbreakers with three rows goes out like this, one key per row per subfield:

// POST body, url decoded for readability full_name=Jordan Ellis email=Jordan.Ellis@example.com dealbreakers[0][criterion]=Wants children dealbreakers[0][importance]=High dealbreakers[1][criterion]=Non smoker dealbreakers[1][importance]=Medium dealbreakers[2][criterion]=Lives within 30 miles dealbreakers[2][importance]=High
What Make does with it Make expands those indexed keys into a real list of rows. I checked this rather than assuming it, because the answer changes the whole design: I posted the body above at a live Make webhook and read back what the scenario saw. dealbreakers came through as a list of three, addressable as {{1.dealbreakers}}, with row 1 reading criterion = Wants children. Posting the same data as clean JSON produced an identical result. So the rows are not lost on arrival, and they do not need to be parsed back out of anything.

Which means the failure people run into is not the webhook. It is what happens after: the rows are a list, and a field mapping that treats them like every other field has nothing sensible to write.

1

Five submissions, posted at a live webhook

These are the five shapes a real intake form produces. Every value in the right hand columns is what Make returned, not what I expected it to return.

SubmissionRows seenFlattened onto the client recordOutcome
Three rows 3 Wants children; Non smoker; Lives within 30 miles Three preference rows written.
One row 1 Wants to relocate One row. A single row still arrives as a list of one, so nothing special is needed.
A row was added then deleted, so the indexes run 0 and 2 2 No pets; Same city Make closes the gap. Two rows, no empty one in the middle.
No rows at all 0 (empty) The one that breaks an unguarded build. Handled below.
Two rows, the second one missing its criterion 2 Wants children;  One row written, one sent to review rather than written blank.
2

The submission that loses itself

builtin:BasicFeeder · the Iterator, and why it needs a gate

If the repeat field is optional, sooner or later somebody submits the form without adding a single row. That submission does not arrive as an empty list. JetFormBuilder sends an empty value instead, so the field is a piece of empty text where a list is expected:

// POST body when the applicant added no rows full_name=Alex Rivera email=alex.rivera@example.com dealbreakers=
Without the gate
the obvious build: webhook, then straight into an Iterator
Iterator receives
empty text
not a list
Run
FAILS
HTTP 500 back to WordPress
Result
Nothing written
the client record is not created either
Measured, not hypothetical: this exact submission returned 500 and wrote nothing. An applicant who skipped an optional section disappears, and the form gives no sign of it.
With the gate
count the rows first, and only iterate when there are some
Rows counted
0
counting is safe on empty text
Route taken
SKIP ROWS
the Iterator never runs
Result
Client written
no preferences, which is the truth
Same submission, same scenario with the gate in place: completed, client record created, zero preference rows. The applicant is in the base.
Why the gate is a count and not a check for empty Counting the rows works on both shapes, a real list and the empty text, which is what makes it usable as the gate. The flattened summary needs the same care for a different reason: the function that pulls one field out of every row raises an error when it is handed something that is not a list, so it sits behind the same count. Make evaluates only the branch it needs, so on an empty repeat field that function is never reached.
3

Where the rows land

airtable:Create a Record · once per row, plus a summary on the client

Repeat rows are one to many, and Airtable is happier with that as its own table. So the scenario writes both, because each answers a different question:

Clients
Preferences Summary
Clients
Preference Rows
Preferences
One row per entry
Needs review
Incomplete entries

The summary and the count sit on the client record so you can read someone's dealbreakers at a glance in the Clients grid without opening anything. The Preferences table holds one row per entry, keyed back to the client by email and carrying the position the applicant put it in, so it is filterable and groupable when you are actually matching people.

Client EmailCriterionImportanceRow
jordan.ellis@example.comWants childrenHigh1
jordan.ellis@example.comNon smokerMedium2
jordan.ellis@example.comLives within 30 milesHigh3
Resubmission The first scenario keeps a person from becoming two client records. Repeat rows need the same treatment or the problem comes back one level down: someone who resubmits with two dealbreakers ends up with four preference rows and nothing to say which pair is current. So before writing this submission's rows, the scenario deletes that client's previous ones. Clear, then write.
4

The half-filled row

a filter per row · write it, or flag it

A repeat row where somebody picked an importance and never typed the criterion is the case with no good silent answer. Writing it produces a blank preference that reads as real when you are matching. Dropping it hides the fact that the form let it through, which is worth knowing because it is usually a form problem, not an applicant problem.

So each row is checked as it is written. Complete rows go to Preferences. Incomplete ones go to a review table with the client, the row number and what did arrive, and the rest of the submission is unaffected:

// two rows in, one submission, decided row by row row 1 criterion="Wants children" importance="High" -> WRITE row 2 criterion="" importance="Medium" -> NEEDS REVIEW

Those two lines are the scenario's own output for that submission, not an illustration of one. The summary on the client record shows the gap too, which is deliberate: it should look slightly wrong there, because it is.

Two corrections to the first blueprint

Building this one meant running both through a real Make account, which turned up two things in the first blueprint that a structural check could not catch. Both are fixed in the file below, so it is worth re-downloading if you kept the earlier one.

What was wrongWhat it would have done
The Airtable update module was named in the singular. The real one is plural, ActionUpdateRecords. Make would have refused the import outright with an unhelpful message about a module it could not find.
The Set Variables module was missing its scope setting. It would have imported cleanly and then failed on your first real submission with a validation error that points at nothing in particular.

Both blueprints now import into a live Make account and come back clean.

Take this one with you too

The repeat field scenario as an importable blueprint, and the raw record of the live run behind every number on this page.