diff --git a/docs/send-table-data.md b/docs/send-table-data.md index 9dfacd30..cafcf9ab 100644 --- a/docs/send-table-data.md +++ b/docs/send-table-data.md @@ -89,7 +89,7 @@ The list input shows a **"Type / to insert column"** placeholder when no column When configuring the list field by hand, select the **list itself** (e.g., `People`), not an indexed element from within that list (e.g., `People.0`, which is just the first person). When you hover over an array-type column in the token picker, you'll see an **Insert all items** option — click it to insert the full list rather than a single indexed element. Selecting a single indexed element instead of the whole array is a common source of confusion: the configuration will show a **"Please add a valid list."** error because an indexed element isn't recognized as a list. -**If the column holds a stringified JSON array** — for example, a text value that looks like `[{"name": "Alice"}, {"name": "Bob"}]`, common when data arrives from an HTTP API call or webhook — Clay won't recognize it as a native list and will show the same **"Please add a valid list."** error. To fix this, click the **gear icon** on the right side of the list input to switch to formula mode, then enter `JSON.parse(/YourColumn)`, replacing `YourColumn` with the name of your column (use `/` to reference it). This converts the text string into a native array that Clay can iterate over. +**If the column holds a stringified JSON array** — for example, a text value that looks like `[{"name": "Alice"}, {"name": "Bob"}]`, common when data arrives from an HTTP API call or webhook, or when a formula column uses `JSON.stringify()` to output a filtered array — Clay won't recognize it as a native list and will show the same **"Please add a valid list."** error. To fix this, click the **gear icon** on the right side of the list input to switch to formula mode, then enter `JSON.parse(/YourColumn)`, replacing `YourColumn` with the name of your column (use `/` to reference it). This converts the text string into a native array that Clay can iterate over. If your table has no rows with data yet, Clay skips this validation and accepts the formula as-is. In that case, run a few rows first so the enrichment column has real output, then re-open the Send Table Data configuration to confirm the list field is valid before running the full table. @@ -216,6 +216,10 @@ When merging data from multiple source tables into a single destination table, f To resolve both: re-run the Send step with **Update existing rows on re-run** on (the default) to push the current values. For fields that change frequently, consider scheduling regular re-runs of the Send step. If you need a value that refreshes on every read without re-running, use [Lookup Rows](https://university.clay.com/docs/lookup-rows) instead. - **All rows in the destination table show the same contact's data (for example, the same email or LinkedIn URL repeated across every row):** the field mappings within the list are referencing a fixed indexed position (like the first contact) instead of each item's own data. Delete the Send Table Data column and recreate it using **Take action on list** from the cell details panel (see [Using Send row for each item in a list](#using-send-row-for-each-item-in-a-list)), which auto-configures both the list source and the correct per-item field mappings. -- **Some rows show `"Invalid send table data inputs … 'listData' … 'Required'"` while others succeed (using `Send row for each item in a list`):** This error means the list column had no data for that specific row — for example, an enrichment returned no results for that company, or a webhook event didn't include the expected field. Clay validates each row individually at runtime, so rows with a valid list array succeed and rows without one fail. **Fix:** Add a [run condition](https://university.clay.com/docs/conditional-runs) to the Send Table Data column so it only runs when the list column is not empty. For example, if your list column is `Find Contacts at Company`, set the condition to run only when `Find Contacts at Company` has a value. +- **Some rows show `"Invalid send table data inputs … 'listData' … 'Required'"` while others succeed (using `Send row for each item in a list`):** This error has two common causes, each with a different fix: + + - **No data for that row** (`received: "undefined"`): the list column had no data for that specific row — for example, an enrichment returned no results for that company, or a webhook event didn't include the expected field. **Fix:** Add a [run condition](https://university.clay.com/docs/conditional-runs) to the Send Table Data column so it only runs when the list column is not empty. For example, if your list column is `Find Contacts at Company`, set the condition to run only when `Find Contacts at Company` has a value. + + - **List column contains a text string instead of an array** (`received: "string"`): the column selected as the list source holds a stringified JSON array — for example, a formula column that uses `JSON.stringify()` to output a filtered list. Clay expects a native array at runtime. **Fix:** In the Send Table Data configuration, click the **gear icon** on the right side of the list input to switch to formula mode, then enter `JSON.parse(/YourColumn)` (replacing `YourColumn` with your column name). This converts the text string into a native array. See [Selecting the right list field manually](#selecting-the-right-list-field-manually) for more detail. - **Send to Table is creating new columns in the destination table instead of populating my existing ones.** By default, `Auto-extract new columns` creates a new column for each incoming field. To route incoming data into an *existing* column instead: open the destination table, click the **"rows from: [source table name]"** cell, hover over the field you want to map (e.g., an email address), and click **Add to column** — then select an existing column from the dropdown (labeled **Map to an existing column**). Repeat for each field you want to map. If the existing column is empty, dismiss the data-overwrite warning safely. To map multiple fields at once, enable **Auto-map existing columns** in the action's advanced settings — Clay will automatically set formulas on all destination columns whose names match incoming fields. Note that for columns with manually entered or CSV-imported values, this will overwrite that existing data. - **Rows created by `Send row for each item in a list` don't have an automatic array-index column.** When Clay expands a list into individual rows in the destination table, it passes each item's own fields plus any additional columns you selected — but it does not include the item's numeric position in the original array. There is also no built-in row ID variable accessible in formula columns. If you need a unique identifier per expanded row — for example, to populate an External ID field for a Salesforce upsert — combine stable fields from the list item. Add a formula column in the destination table that concatenates fields which together uniquely identify each record. For employment history data, for instance, combining contact ID, company name, and start date (`{{Contact ID}} + "-" + {{Company Name}} + "-" + {{Start Date}}`) produces a stable composite key per job entry. Use enough fields to make the combination unique for your data. (Note: Clay's formula engine does not support object spread syntax like `{ ...item, _index: idx }`, so you can't pre-augment list items with an index in a formula column before sending.) **For upsert workflows, use only deterministic (stable) field values in your ID.** Avoid basing the ID on `Math.random()`: because `Math.random()` generates a new value every time the formula column re-runs, re-running the column assigns a different ID to each existing row and causes the upsert target to create duplicates instead of updating the originals.