fix(designer): scope Set Variable dropdown for pasted scopes#9403
Merged
lambrianmsft merged 2 commits intoJul 18, 2026
Conversation
Contributor
🤖 AI PR Validation ReportPR Review ResultsThank you for your submission! Here's detailed feedback on your PR title and body compliance:✅ PR Title
✅ Commit Type
✅ Risk Level
✅ What & Why
✅ Impact of Change
✅ Test Plan
|
| Section | Status | Recommendation |
|---|---|---|
| Title | ✅ | No changes needed |
| Commit Type | ✅ | No changes needed |
| Risk Level | ✅ | Low is correct and matches label |
| What & Why | ✅ | No changes needed |
| Impact of Change | ✅ | No changes needed |
| Test Plan | ✅ | Unit tests present and verified |
| Contributors | Credit contributors if any | |
| Screenshots/Videos | Optional clip of dropdown behavior |
All required checks pass. This PR is compliant and ready to merge. Consider addressing the two non-blocking nudges (Contributors, optional screenshot).
Powered by: Copilot CLI (claude-opus-4.8) | Last updated: Fri, 17 Jul 2026 06:15:58 GMT
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes incorrect variable scoping after copy/pasting scoped actions (e.g., a Condition containing Set Variable) by ensuring pasted nodes have valid parentNodeId/graph metadata, recomputing upstream metadata reliably, and making the variable-name dropdown strictly honor upstream scope (v1 + v2), with new unit coverage to prevent regressions.
Changes:
- Correct pasted scope metadata so
parentNodeIdpoints at a realnodesMetadatakey (and persist the corrected metadata into reducer state). - Remove the “fallback to all variables” behavior so
VARIABLE_NAMEdropdown only shows genuinely upstream variables. - Add targeted Vitest suites (including paste-matrix coverage) to validate scoping across paste targets and nesting patterns.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/tabs/parametersTab/index.tsx | Removes all-variables fallback; dropdown options now come strictly from upstream-scoped variables. |
| libs/designer/src/lib/ui/panel/nodeDetailsPanel/tabs/parametersTab/test/getEditorAndOptions.spec.ts | Updates tests to assert strict upstream-only variable dropdown behavior. |
| libs/designer/src/lib/core/parsers/pasteScopeInWorkflow.ts | Persists corrected graphId/parentNodeId back into reducer state to avoid stale metadata references. |
| libs/designer/src/lib/core/parsers/test/pasteScopeMatrix.spec.ts | Adds end-to-end paste matrix tests validating variable scoping for pasted scopes. |
| libs/designer/src/lib/core/parsers/test/pasteScopeInWorkflow.spec.ts | Adds regression tests asserting corrected parentNodeId persistence in state. |
| libs/designer/src/lib/core/actions/bjsworkflow/copypaste.ts | Fixes pasted top-node parentNodeId seeding; extends upstream token seeding for scope paste; triggers upstream recompute after paste. |
| libs/designer/src/lib/core/actions/bjsworkflow/test/copypaste.spec.ts | Adds unit tests for upstream extension helper used during scope paste token seeding. |
| libs/designer-v2/src/lib/ui/panel/nodeDetailsPanel/tabs/parametersTab/index.tsx | Mirrors v1: strict upstream-only variable dropdown options. |
| libs/designer-v2/src/lib/ui/panel/nodeDetailsPanel/tabs/parametersTab/test/getEditorAndOptions.spec.ts | Mirrors v1: asserts strict upstream-only variable dropdown behavior. |
| libs/designer-v2/src/lib/core/parsers/pasteScopeInWorkflow.ts | Mirrors v1: writes corrected metadata back into state to avoid stale references. |
| libs/designer-v2/src/lib/core/parsers/test/pasteScopeMatrix.spec.ts | Mirrors v1: paste matrix tests for variable scoping correctness. |
| libs/designer-v2/src/lib/core/parsers/test/pasteScopeInWorkflow.spec.ts | Mirrors v1: regression tests for corrected parentNodeId persistence. |
| libs/designer-v2/src/lib/core/actions/bjsworkflow/copypaste.ts | Mirrors v1: metadata seeding + upstream token seeding extension + upstream recompute after paste. |
| libs/designer-v2/src/lib/core/actions/bjsworkflow/test/copypaste.spec.ts | Mirrors v1: unit tests for upstream extension helper. |
preetriti1
approved these changes
Jul 16, 2026
When a Condition (or any scope) containing a Set Variable was copy-pasted into another scope — a Condition branch or a For each body — the pasted Set Variable's Name dropdown showed the wrong set of variables: empty in nested Conditions, or leaking out-of-scope variables (including ones from a parallel branch) when pasted into a For each. Selecting such a variable let the user reference an uninitialized variable and break scope. Root cause (two coordinated defects in the scope-paste path): 1. pasteScopeOperation seeded the pasted top node's `parentNodeId` with the relationship `parentId`, which is an edge-placement node (e.g. a `<scope>-#subgraph` card) and is not a nodesMetadata key. The parent-chain walk in getUpstreamNodeIds therefore could not climb to ancestor scopes. 2. pasteScopeInWorkflow recomputed the correct `parentNodeId` (the containing graph id) but assigned it to a detached object: the earlier metadata copy loop had already written the pasted node's entry into state by reference, so the correction never reached state.nodesMetadata. The final upstream recompute (updateAllUpstreamNodes -> getTokenNodeIds) then read the stale placeholder parentNodeId and mis-scoped the dropdown. Fix: - copypaste.ts: set the pasted scope node's `parentNodeId` to the containing `graphId` (undefined at root) instead of the edge-placement `parentId`. - pasteScopeInWorkflow.ts: write the corrected metadata back into state.nodesMetadata so the recomputed graphId/parentNodeId persist. - Restore strict upstream scoping in the Set Variable editor (getEditorAndOptions) and add extendUpstreamNodeIdsForScopePaste so token initialization seeds the enclosing scope's upstream tokens. Tests: - pasteScopeInWorkflow.spec.ts (v1 + v2): the pasted node's parentNodeId is persisted as the containing graph id (not the subgraph card) and stays undefined at root. - copypaste.spec.ts (v1 + v2): extendUpstreamNodeIdsForScopePaste surfaces ancestor variables while excluding parallel-branch variables. - getEditorAndOptions.spec.ts (v1 + v2): strict scoping — empty upstream yields no options; scoped upstream yields only in-scope variables. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: af9ea0d5-71e4-45d9-9790-0edc869beadd
lambrianmsft
force-pushed
the
lambrian/scope-paste-fix-followup
branch
from
July 16, 2026 23:41
73f93da to
5ba5f13
Compare
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 free
to 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.
Commit Type
Risk Level
What & Why
Customers reported that after copy-pasting a scope (for example a
Conditioncontaining aSet Variable) into another scope, the pastedSet Variable's Name dropdown showed the wrong variables: empty for nested Conditions, or leaking out-of-scope / parallel-branch variables when pasting into aFor each. That let a user reference an uninitialized variable and break scope, even though code view showed the variable correctly.Root cause is broken graph metadata on the pasted node. Two coordinated defects:
copypaste.ts(pasteScopeOperation) seeded the pasted top node'sparentNodeIdwith the relationshipparentId, which for a branch-top paste is an edge-placement card id (e.g.Condition-elseActions-#subgraph), not anodesMetadatakey. The parent-chain walk ingetUpstreamNodeIdsdead-ends there and never climbs to the ancestor scope where the variable is initialized.pasteScopeInWorkflow.tsreducer copied each pasted node's metadata into state by reference, then reassigned a new corrected object to the localnodesMetadata[nodeId]. Because state still held the old reference, the correction never reached state, so the finalupdateAllUpstreamNodesrecompute read the stale card-idparentNodeId.Approach
parentNodeIdwith the containing graph id (graphId, orundefinedat root) so it references a realnodesMetadatakey that the parent-chain walk can climb.state.nodesMetadata[nodeId] = nodesMetadata[nodeId]) so the fix survives to the upstream-node recompute.VARIABLE_NAMEeditor branch (getEditorAndOptions) so the dropdown only offers variables that are genuinely upstream, instead of falling back to all variables.Both the
designer(v1) anddesigner-v2copies are updated in lockstep.Impact of Change
parentNodeIdon a pasted scope node is now guaranteed to be a validnodesMetadatakey (orundefinedat root). No API changes.Test Plan
Added a paste-matrix scope-correctness suite (
pasteScopeMatrix.spec.ts, v1 + v2) that drives the realpasteScopeInWorkflowreducer, then resolves the nested Set Variable viagetUpstreamNodeIds+getAvailableVariables. It covers the full matrix of Set Variable nested in a copied {Condition, Scope} pasted into {Condition, Scope, For each}, asserting the in-path Initialize Variable appears and a separate-path Initialize Variable is excluded, plus positive cases where a target downstream of both vars sees both. Verified these tests fail when the reducer persist line is removed, so they genuinely guard the fix. Also added reducer metadata tests and copypaste helper tests. Targeted Vitest is green and Biome is clean.Contributors
Screenshots/Videos
N/A