Skip to content

Fix evented wflow nested loop#16312

Merged
taofeeq-deru merged 4 commits into
mainfrom
fix-evented-wflow-nested-loop
May 7, 2026
Merged

Fix evented wflow nested loop#16312
taofeeq-deru merged 4 commits into
mainfrom
fix-evented-wflow-nested-loop

Conversation

@taofeeq-deru

@taofeeq-deru taofeeq-deru commented May 7, 2026

Copy link
Copy Markdown
Contributor

Description

Fix evented wflow nested loop

Related Issue(s)

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Test update

Checklist

  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works
  • I have addressed all Coderabbit comments on this PR

ELI5 (Explain Like I'm 5)

This PR fixes a bug where a workflow run started inside a loop (a "nested workflow") didn't let its parent loop resume or finish correctly. It detects when a finished child run belongs to a loop step in the parent and routes the completion into the loop handler so the parent can continue; tests ensure nested do-until and do-while loops work.

Changes Made

Bug Fix: Nested Loop Handling in Evented Workflows

  • processWorkflowEnd now inspects parentWorkflow.stepGraph[parentWorkflow.executionPath[0]] and, if that step is a loop, calls processWorkflowLoop with the parent workflow's richer execution metadata so the parent loop resumes/handles the nested run correctly. If the parent step is not a loop it falls back to publishing a workflow.step.end for the parent (including parentContext and nestedRunId).
  • Added cleanupRun to remove abort controllers, parent-child relationship entries, and runFormats when a workflow completes; cancelRunAndChildren recursively aborts child runs.
  • parentChildRelationships map added to track child runId → parent runId for nested workflows and used during cancellation/cleanup.

Type/API Updates

  • Expanded ParentWorkflow public type (packages/core/src/workflows/evented/workflow-event-processor/index.ts) to include execution/resume fields required by nested handling:
    • Added: stepGraph: StepFlowEntry[], activeSteps: Record<string, boolean>, resumeSteps: string[], resumeData: any, input: any
    • Added optional: parentContext?: { workflowId: string; input: any }
    • Retained existing fields (workflowId, runId, executionPath, resume, stepResults, stepId, parentWorkflow?)

Tests

  • workflows/_test-utils/src/domains/loops.ts: expanded test utilities to add nested loop coverage:
    • New nested dountil and nested dowhile workflow registrations (inner increment workflows used as loop bodies) and corresponding mocks.
    • Tests exercise nested-until and nested-while scenarios and include other loop cases (immediate-exit, non-nested loops).

Release/Packaging

  • .changeset/rare-bikes-wear.md: new changeset marking a patch for @mastra/core describing "Fix nested loops in evented workflow".

Files Touched (high level)

  • packages/core/src/workflows/evented/workflow-event-processor/index.ts — core logic: processWorkflowEnd branching, ParentWorkflow type expansion, abort controller & parent-child tracking and cleanup.
  • workflows/_test-utils/src/domains/loops.ts — added nested loop workflow definitions and test mocks.
  • .changeset/rare-bikes-wear.md — changeset entry.

Impact

  • Fixes nested-loop completion/resume behavior for evented workflows and adds tests to prevent regressions.
  • Low-risk patch scope but touches core event-processing logic; reviewers should focus on correctness of processWorkflowEnd → processWorkflowLoop interaction, cleanup/cancellation semantics, and the ParentWorkflow shape used across event payloads.

@taofeeq-deru taofeeq-deru requested a review from rase- May 7, 2026 15:10
@vercel

vercel Bot commented May 7, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
mastra-playground-ui Ready Ready Preview, Comment May 7, 2026 3:36pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
mastra-docs-1.x Skipped Skipped May 7, 2026 3:36pm

Request Review

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

ParentWorkflow gains execution metadata fields. processWorkflowEnd now routes nested loop completions into loop processing; start/resume payloads include richer parent metadata. Two nested-loop test workflows and a changeset were added.

Changes

Nested Loops Evented Workflow Fix

Layer / File(s) Summary
Type Contract
packages/core/src/workflows/evented/workflow-event-processor/index.ts
ParentWorkflow adds stepGraph, activeSteps, resumeSteps, resumeData, input, and optional parentContext.
Core Logic
packages/core/src/workflows/evented/workflow-event-processor/index.ts
processWorkflowEnd inspects the parent's first step via parentWorkflow.stepGraph[parentWorkflow.executionPath[0]]; loop parents are handled via processWorkflowLoop, others emit workflow.step.end with state and parentContext.
Start/Resume Payloads
packages/core/src/workflows/evented/workflow-event-processor/index.ts
Nested start/resume payloads updated to include expanded parent execution metadata (stepGraph, activeSteps, resumeData/resumeSteps, input).
Test Workflows
workflows/_test-utils/src/domains/loops.ts
Adds nested-until and nested-while workflow entries using inner increment workflows, mock factories, and reset support.
Test Cases
workflows/_test-utils/src/domains/loops.ts
Adds tests that run the nested workflows, assert success, verify finalValue: 12, and check nested increment step outputs and final outputs.
Release Notes
.changeset/rare-bikes-wear.md
Adds a changeset documenting a patch release for @mastra/core describing the nested loops fix.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Fix evented wflow nested loop' is concise, descriptive, and directly related to the main change of fixing nested loop handling in evented workflows.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-evented-wflow-nested-loop

Comment @coderabbitai help to get the list of available commands and usage tips.

@changeset-bot

changeset-bot Bot commented May 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d4b8e35

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 23 packages
Name Type
@mastra/core Patch
mastracode Patch
@mastra/mcp-docs-server Patch
@internal/playground Patch
@mastra/client-js Patch
@mastra/opencode Patch
@mastra/longmemeval Patch
mastra Patch
@mastra/deployer-cloud Patch
@mastra/deployer-vercel Patch
@mastra/playground-ui Patch
@mastra/react Patch
@mastra/server Patch
@mastra/deployer Patch
create-mastra Patch
@mastra/express Patch
@mastra/fastify Patch
@mastra/hono Patch
@mastra/koa Patch
@mastra/nestjs Patch
@mastra/deployer-cloudflare Patch
@mastra/deployer-netlify Patch
@mastra/temporal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/workflows/evented/workflow-event-processor/index.ts`:
- Around line 373-374: The code only looks at
parentWorkflow.stepGraph[parentWorkflow.executionPath[0]] which inspects the
root segment of executionPath and misses nested active parents; update the
loop-detection logic in the workflow-event-processor to use the current/deepest
active segment (e.g., the last element of parentWorkflow.executionPath or derive
the active index) when selecting the step from parentWorkflow.stepGraph, handle
the case where executionPath may be empty/undefined, and ensure the subsequent
branch that checks step?.type === 'loop' now correctly detects nested loops so
completion routing doesn't fall back to workflow.step.end.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c90e9bbe-da32-4dc0-a1d6-8e43fcd94a12

📥 Commits

Reviewing files that changed from the base of the PR and between 1b7d443 and e3eb943.

📒 Files selected for processing (3)
  • .changeset/rare-bikes-wear.md
  • packages/core/src/workflows/evented/workflow-event-processor/index.ts
  • workflows/_test-utils/src/domains/loops.ts

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/workflows/evented/workflow-event-processor/index.ts`:
- Around line 62-70: The type for stepGraph is incorrect: change the property
declaration of stepGraph from Record<string, StepFlowEntry> to StepFlowEntry[]
so it matches how the code indexes it by numeric executionPath values (e.g.,
references like stepGraph[executionPath[0]!] and the StepFlowEntry[] usage at
other places); update the interface/type that contains stepGraph accordingly so
the compiler and callers treat it as an array of StepFlowEntry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f8b89c87-fc7b-4cd8-9eb5-734d0d187f86

📥 Commits

Reviewing files that changed from the base of the PR and between e3eb943 and a93f4c2.

📒 Files selected for processing (1)
  • packages/core/src/workflows/evented/workflow-event-processor/index.ts

Comment thread packages/core/src/workflows/evented/workflow-event-processor/index.ts Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/core/src/workflows/evented/workflow-event-processor/index.ts (1)

373-375: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the full executionPath when detecting loop parents.

Line 374 still inspects only executionPath[0], so a loop nested under parallel/conditional is misclassified and falls back to workflow.step.end. That leaves the nested-loop bug in place for non-root loops.

Suggested fix
-      const step = parentWorkflow.stepGraph[parentWorkflow.executionPath[0]!];
+      const step = getStep(parentWorkflow as unknown as Workflow, parentWorkflow.executionPath);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/workflows/evented/workflow-event-processor/index.ts` around
lines 373 - 375, The code checks only parentWorkflow.executionPath[0] to find
the parent step so nested loops under parallel/conditional get misclassified;
update the lookup to use the full executionPath (e.g., use the last index or
traverse the path) when resolving the parent step in parentWorkflow.stepGraph
instead of executionPath[0], then keep the existing check step?.type === 'loop'
so nested loop parents are correctly detected and avoid falling back to
workflow.step.end.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/workflows/evented/workflow-event-processor/index.ts`:
- Around line 407-411: The code is incorrectly forwarding the nested workflow's
resume metadata (resumeSteps, resumeData, activeSteps) into the parent
completion event; instead pass the parent's metadata so the parent's bookkeeping
isn't overwritten. Update the call/context that currently passes resumeSteps,
resumeData, and activeSteps to use the parent's values (e.g.,
parentWorkflow.resumeSteps, parentWorkflow.resumeData,
parentWorkflow.activeSteps) alongside stepResults: parentWorkflow.stepResults
and prevResult before calling processWorkflowStepEnd (or the function that
continues the parent step).

---

Duplicate comments:
In `@packages/core/src/workflows/evented/workflow-event-processor/index.ts`:
- Around line 373-375: The code checks only parentWorkflow.executionPath[0] to
find the parent step so nested loops under parallel/conditional get
misclassified; update the lookup to use the full executionPath (e.g., use the
last index or traverse the path) when resolving the parent step in
parentWorkflow.stepGraph instead of executionPath[0], then keep the existing
check step?.type === 'loop' so nested loop parents are correctly detected and
avoid falling back to workflow.step.end.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 47243b6d-073a-45d1-b292-7039c8197311

📥 Commits

Reviewing files that changed from the base of the PR and between a93f4c2 and d4b8e35.

📒 Files selected for processing (1)
  • packages/core/src/workflows/evented/workflow-event-processor/index.ts

@taofeeq-deru taofeeq-deru merged commit 4c0e286 into main May 7, 2026
52 checks passed
@taofeeq-deru taofeeq-deru deleted the fix-evented-wflow-nested-loop branch May 7, 2026 16:13
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.

2 participants