Skip to content

7.5 For-Each Loops

The For-Each Loop is the core pattern for processing every item in a list with AI or any automation that takes time, and then collecting all results back into the parent row once every item is finished.

Tutorial first?

If you haven't built one yet, start with 5.4 For-Each Loops in the tutorial for a step-by-step walkthrough.


Overview

The pattern involves three connected parts:

Parent Row

    ├─ Sub-taible column (list of items)
    │       │
    │       ├─ Child Row 1 ──► [AI / API / Code column]  ──► Done ✅
    │       ├─ Child Row 2 ──► [AI / API / Code column]  ──► Done ✅
    │       └─ Child Row N ──► [AI / API / Code column]  ──► Done ✅
    │                                    │
    │                    (Completion tracker fires when ALL are Done)
    │                                    │
    ├─ Pull Data column ◄────────────────┘  (collects results from children)

    └─ Downstream columns (summarize, aggregate, send, ...)

Without this pattern, parent columns that depend on child results fire immediately when first triggered — before the children have finished their async work — and produce partial or empty output.

With this pattern, the parent waits for a signal that all children are done before collecting results.


Configuration Reference

Part 1: Completion Tracking (sub-taible column in parent)

Completion tracking is configured on the sub-taible column in the parent taible — the column that holds the link to the child taible.

Where to find it: Edit column → scroll to "Completion Tracking" section.

SettingTypeDescription
Track CompletionToggleEnables watching for all child rows to reach Done state
Track ColumnTextThe technical name of the child column to monitor (e.g. analysis)

How it works:

When "Track Completion" is enabled, the system monitors all child rows that share the same parent_row_id. Every time a child row's tracked column changes state, the system checks whether every sibling row (all children of the same parent) has the tracked column in Done state.

When the last child crosses into Done, the system automatically re-triggers all dependent columns in the parent row that are waiting for sub-taible completion.

Track Column must be the technical name

Use the column's internal name (lowercase, underscores) — the same name shown in template expressions. Not the display label. For example: analysis, not Analysis or AI Analysis.


Part 2: Pull Data Column (in parent)

The Pull Data node is the standard way to collect child results into the parent. It reads a single column from all child rows belonging to the current parent and returns the values as a list.

Where to find it: Add Column → Pull Data

SettingDefaultDescription
Source TaibleThe child (sub-) taible to pull from
Source ColumnWhich column's values to collect
Filter by Parent RowONOnly pull rows belonging to the current parent row. Leave ON for For-Each loops.
Wait for All Rows to CompleteONIf any child row's source column is not yet Done, skip this run and wait to be re-triggered.

Output: A list of values, one entry per child row that has a non-empty value in the source column.

// Example output for 3 children:
["Analysis of topic A...", "Analysis of topic B...", "Analysis of topic C..."]

The output type of the Pull Data column matches the child column's output type, wrapped in a List.


Part 3: Run Configuration (Pull Data column)

For the pull data column to be triggered by sub-taible completion, it must declare the sub-taible column as a dependency in its Run Configuration.

Dependency to add: The sub-taible column in the parent taible (the one with Track Completion enabled).

This is what connects the completion signal from Part 1 to the Pull Data column in Part 2. Without this dependency the re-trigger from Part 1 won't reach the Pull Data column.


Full Setup Checklist

In the child (sub-) taible:

  • [ ] Add the column that does the work (AI, API, Custom Code, etc.)
  • [ ] Set that column's dependency on the input column(s)

In the parent taible — sub-taible column:

  • [ ] Open column settings → Completion Tracking section
  • [ ] Enable Track Completion
  • [ ] Set Track Column to the child column's technical name

In the parent taible — Pull Data column:

  • [ ] Source Taible: the sub-taible
  • [ ] Source Column: the child column to collect
  • [ ] Filter by Parent Row: ON
  • [ ] Wait for All Rows to Complete: ON
  • [ ] Run Configuration → dependency on the sub-taible column

In the parent taible — downstream column (summarize, report, etc.):

  • [ ] Dependency on the Pull Data column
  • [ ] Run mode: Dependent - Once (runs when Pull Data delivers a value)

Execution Flow

The exact sequence of events when a parent row is created with a list of items:

1. Parent row created
2. Sub-taible column receives list data
3. System creates one child row per list item
4. Each child row's work column is queued and runs (in parallel)

   ... time passes (seconds to minutes depending on workload) ...

5. Child row #1 finishes → completion check: 1/N done, skip
6. Child row #2 finishes → completion check: 2/N done, skip
   ...
7. Child row #N finishes → completion check: N/N done → ALL DONE
8. System re-triggers parent row's dependent columns
9. Pull Data column runs:
   - Checks all child rows → all Done ✅
   - Collects values → publishes list
10. Downstream parent columns run (summarize, send, etc.)

When NOT to Use Completion Tracking

Completion tracking adds overhead. You don't need it when:

  • Child columns are instant (simple math, string manipulation) — the children finish before the parent dependency check even runs. Use a regular dependency instead.
  • The parent only needs partial results — e.g., "notify me when any child finds a match." Use a regular dependency without "wait for all."
  • Children are processed one at a time (rate-limited) and the parent should accumulate results incrementally. Use a different aggregation strategy.

Use completion tracking specifically for: AI calls, external API calls, web scraping, file processing — anything async that takes unpredictable time.


Relationship to Other Patterns

PatternWhen to use
For-Each Loop (this page)Process N items in parallel, collect all results when done
Parent → Child data flowPass parent data down to children as input (see 7.3)
Simple roll-upChildren have instant calculations; aggregate with Custom Code in parent
Cross-row analysisPull data from a completely separate taible, not a sub-taible (see 10.3)

Common Patterns

Pattern: AI Batch Analysis → Summary

Parent: Report Request
  └─ items (sub-taible) ── Track Completion: "analysis"
        ├─ Child: item_name → analysis (LLM)
        └─ ... N children

Parent: all_analyses (Pull Data from sub-taible.analysis, Wait=ON)
Parent: final_summary (LLM, depends on all_analyses)

Pattern: API Enrichment → Aggregated Result

Parent: Company
  └─ employees (sub-taible) ── Track Completion: "enriched_profile"
        ├─ Child: name, email → enriched_profile (API call)
        └─ ... N children

Parent: all_profiles (Pull Data, Wait=ON)
Parent: company_summary (depends on all_profiles)

Pattern: Document Processing → Risk Report

Parent: Contract
  └─ clauses (sub-taible) ── Track Completion: "risk_assessment"
        ├─ Child: clause_text → risk_assessment (LLM)
        └─ ... N children

Parent: clause_risks (Pull Data, Wait=ON)
Parent: overall_risk_score (Custom Code, depends on clause_risks)

Troubleshooting

Parent fires before children are done

Symptom: Pull Data returns fewer items than expected, or returns null/empty.

Cause: "Wait for All Rows to Complete" is not enabled on the Pull Data column, or "Track Completion" is not enabled on the sub-taible column (so no re-trigger signal is sent).

Fix: Enable both settings. Both are required.

Parent never fires after children complete

Symptom: All child rows show "Done" but the parent Pull Data column stays Idle.

Cause 1: "Track Completion" is enabled but "Track Column" doesn't match the child column name. The system checks for Done on the named column — a typo means the check never succeeds.

Cause 2: The Pull Data column is not listed as a dependency of the sub-taible column (or vice versa). Check Run Configuration.

Cause 3: One or more child rows failed (red status). The system only fires when all rows are Done, not when some are Failed. Fix the failing child rows first.

Results are correct but downstream column doesn't run

The downstream column (e.g., final_summary) must declare the Pull Data column (all_analyses) as a dependency. Without this, it won't know to re-run when Pull Data delivers a value.

Pull Data returns an empty list even though children are Done

Check that the source column name in Pull Data matches the child column's technical name exactly. Also verify that the child column's cells actually contain data (not null/empty).


See Also

Built with VitePress