Skip to content

fix(executor): bound condition loops and reject unnamed variable assignments - #9463

Open
waleedlatif1 wants to merge 3 commits into
stagingfrom
fix/loop-iteration-ceiling
Open

waleedlatif1 wants to merge 3 commits into
stagingfrom
fix/loop-iteration-ceiling

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Two executor gaps let a workflow loop forever without any error.

Condition-driven loops had no bound. A While loop, or a Do While loop given a condition, stopped only when its condition turned false. If the body never changed what the condition checks, the loop repeated until the run's timeout. The original While design relied on that timeout, but billing-disabled (self-hosted) deployments now run untimed, so there the loop repeated until the process was stopped. Hosted runs still used their full timeout.

These loops now stop after DEFAULTS.MAX_CONDITION_LOOP_ITERATIONS (10,000) iterations if the condition is still true. The run then fails with an error log on the loop container ("While loop stopped after 10,000 iterations with its condition still true…"). Exiting quietly would pass a truncated results downstream as if the condition had ended the loop. A condition that turns false on the last allowed iteration still exits normally. For, For Each and count-driven Do While loops keep their configured count, and the ceiling does not apply to them.

The ceiling is per loop run: nested loops reset their scope on each outer iteration, and scope.iteration already carries over through pause/resume snapshots, so no snapshot shape changes. 10,000 leaves room for realistic polling (a 1 s poll runs about 2.8 h, longer than the default hosted async timeout). A tight loop with a stuck condition now fails in seconds to minutes instead of running until the timeout.

Variables assignments without a name were dropped. parseAssignments skipped any row with a blank variableName, so an update meant to advance loop state did nothing and raised no error. This is how a stuck While condition usually happens. The new rule:

  • A row targets the variable it names, or the one its variableId selects. A row with an id but no name previously did nothing, even though the variable existed.
  • A row that targets no variable but carries a value fails the block: Assignment N sets a value but names no variable….
  • Blank rows, the empty row the editor adds by default, are still ignored.
  • A row that omits type takes its target variable's type, so { variableName: 'count', value: 1 } stays a number. Before, it was stored as the string '1', which breaks <variable.count> + 1 in a loop counter.

The block's published input description said "objects with name and value properties". name is not the field the handler reads, so authoring tools that read the catalog were steered to the wrong key. It now names variableName.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

  • New executor/execution/condition-loop-ceiling.test.ts runs real workflows through DAGExecutor:
    • While and conditional Do While loops with a condition that never turns false fail at exactly 10,000 iterations, with the error on the loop's block log. On the previous code the same tests ran until the test's cancellation guard stopped them at 30,000.
    • A condition that turns false on iteration 10,000 still succeeds.
    • For and count-driven Do While loops configured for 10,005 iterations still run all 10,005.
  • handler.test.ts:
    • A value set through a blank name, through a name key, or through an unknown id with no name now fails. On the previous code all three passed silently.
    • Blank editor rows are still skipped.
    • A row with an id but no name updates its variable.
  • vitest run executor lib/workflows lib/catalog blocks serializer: 335 files, 4607 tests pass. tsc --noEmit is clean for apps/sim, as are biome, check:test-types, check:comment-hygiene, check:utils and check:source-conventions.

Reviewers: does the 10,000 ceiling size fit how condition loops are used?

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…t unnamed variable assignments

A While loop, or a Do While loop given a condition, had no iteration bound: a body
that never changed what the condition checks repeated until the run timed out, and
billing-disabled deployments run untimed, so it repeated until the process stopped.
Such loops now fail with an error on the loop after 10,000 iterations if the
condition is still true. For, For Each and count-driven Do While loops are unchanged.

A Variables assignment with a value but no variable name was skipped without an
error. It now fails the block; blank editor rows are still ignored, and a row that
selects its variable by id alone now updates that variable. The block's published
input description named the wrong field ("name"), which is corrected to variableName.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@vercel

vercel Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Ignored Ignored Preview Oct 30, 2026 3:44am UTC

Request Review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@greptile-apps

greptile-apps Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issues remain.

Summary

The PR caps condition-driven loops at 10,000 iterations and rejects variable assignments that supply a value without a target.

  • Condition loops fail when they stay true for 10,000 iterations.
  • Variable assignments use their selected target and report missing ones.

Reviews (3) · Last reviewed commit: "chore(executor): shrink the explicit-any..." · Reviewed by Greptile

Comment thread apps/sim/executor/handlers/variables/handler.ts Outdated
Comment thread apps/sim/executor/handlers/variables/handler.ts Outdated
Comment thread apps/sim/executor/execution/condition-loop-ceiling.test.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 8 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/executor/handlers/variables/handler.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 8 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

This branch was previously deployed

1 inactive (outdated) deployment
Preview — f85eb7cf Deployed Oct 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant