Uh oh!
There was an error while loading. Please reload this page.
fix(web): clone subworkflowContexts tree in processEvent (#307) - #308
Merged
Jason Robert (jrob5756) merged 2 commits intoJul 16, 2026
Merged
Conversation
processEvent already cloned nodes/groupProgress/eventLog/activityLog on every event so React/Zustand reference-equality checks pick up changes, but subworkflowContexts was never cloned. Handlers routed through activeTarget()/resolveContext()/resolveSlotPath() (subworkflow_started, subworkflow_completed, agent events carrying a subworkflow_path, etc.) mutate nested ctx.nodes/groupProgress/routes/highlightedEdges and push onto subworkflowContexts/children in place, so nothing forced a fresh reference anywhere in that tree. Any selector/useMemo keyed on subworkflowContexts (e.g. useViewedNodes/useViewedGraphData) could therefore miss an update, producing the reported symptom: an agent node adjacent to a sub-workflow step visually stuck on "running" even though the store's underlying data was already correct. Adds cloneSubworkflowContexts(), a structural clone of the SubworkflowContext tree, wired into processEvent. replayState already rebuilds subworkflowContexts fresh per replay and commits once, so it needed no change. Also adds a minimal Vitest setup for the frontend (previously zero frontend tests existed) plus a regression test exercising both the root-adjacent-to-subworkflow case and a node update nested inside a running child context; verified the test fails without the fix and passes with it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a7be2391-c5bd-44d9-a978-12fe7832735e
…ests into CI Addresses code-review feedback on #308: - Replace the whole-tree clone of subworkflowContexts with a path-scoped clone-on-write (cloneContextShallow + resolveMutableContext/ resolveMutableSlotPath). Only the top-level array and the ancestor chain down to the context actually being mutated get a new reference; untouched sibling subtrees (including their own descendants) keep their existing reference. This avoids deep-cloning the entire sub-workflow tree on every single event (including root-level events that never touch a sub-workflow), and avoids triggering re-renders in components viewing an unrelated branch. - Add regression tests for: nested (grandchild) sub-workflow propagation, concurrent for_each siblings not cloning each other, root-only events never touching subworkflowContexts at all, and field preservation across a clone-and-mutate cycle. Verified each new test fails when the corresponding part of the fix is reverted. - Switch resetStore() to a shared beforeEach. - Add a `frontend` CI job (typecheck + Vitest + build) so the regression suite actually runs on every PR instead of only when invoked manually. - Trim doc-comment cross-references that were prone to drift (pointing at another comment / naming specific hook consumers / citing the issue number as load-bearing). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a7be2391-c5bd-44d9-a978-12fe7832735e
Jason Robert (jrob5756)
commented
Jul 16, 2026
CollaboratorAuthor
Ran a multi-agent code review (code-reviewer, pr-test-analyzer, comment-analyzer) against the original commit and addressed the findings in a follow-up commit:
All 6 frontend tests pass, |
Uh oh!
There was an error while loading. Please reload this page.
Jason Robert (jrob5756)
deleted the
fix/307-subworkflow-node-stuck-running
branch
July 16, 2026 20:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes#307: an agent node adjacent to a
type: workflowsub-workflow stepcould render stuck showing "running" even though the underlying store data
was already
completed— a pure rendering/reactivity desync, not an enginedata bug (confirmed correct via the detail panel per the issue report).
Root cause
processEventinworkflow-store.tsclonesnodes/groupProgress/eventLog/activityLogon every event so React/Zustand reference-equalitychecks pick up changes (per
replaceNode's own doc comment: "Create a newreference for a node to ensure React/ReactFlow detects the change") — but
it never cloned
subworkflowContexts. Handlers reached throughactiveTarget()/resolveContext()/resolveSlotPath()(subworkflow_started,subworkflow_completed, agent events carrying asubworkflow_path, etc.)mutate nested
ctx.nodes/groupProgress/routes/highlightedEdgesinplace, and
subworkflow_startedpushes ontosubworkflowContexts/childrenarrays in place. Nothing forced a fresh reference anywhere inthat tree, so any selector/
useMemokeyed onsubworkflowContexts(e.g.useViewedNodes/useViewedGraphDatainuse-viewed-context.ts) could missan update depending on render/batching timing.
Fix
cloneSubworkflowContexts(): a structural clone of theSubworkflowContexttree (each context plus its ownnodes/groupProgress/routes/highlightedEdges/children/etc.), wired intoprocessEventalongside the existing clones.replayState: it already rebuildssubworkflowContextsfreshfrom
{}per replay and commits once at the end, so it needed no change.Testing
There were previously zero frontend automated tests. Added a minimal
Vitest setup (
vitestdevDependency,vitest.config.ts,npm run test,and a
make test-frontendtarget) plus a regression test inworkflow-store.test.tsthat:adjacent
subworkflow_started/subworkflow_completedpair) and assertsthe agent's node stays
completedandsubworkflowContextsgets a freshreference on every mutating event.
sub-workflow context (via
subworkflow_path), asserting the samereference-identity behavior.
cloneSubworkflowContextscall and confirmed both tests fail with theexact
Object.isreference-equality assertion; restored the fix andconfirmed both pass again.
Closes#307.