Severity: low. Found in the 1.0.0-alpha9 pre-release audit (finding L1). It is not reachable on any shipped example workflow, so this is a latent correctness sharp edge rather than a live bug. Filing it so the resume fallback is made branch-aware before a real workflow hits the combination.
Where
orchestra_interaction_webform: OrchestraInteractionHandler::resumeTarget() in modules/orchestra_interaction_webform/src/Plugin/WebformHandler/OrchestraInteractionHandler.php, and the fallback it calls, InteractionResolver::parkedTokenAtNode() in modules/orchestra_interaction/src/InteractionResolver.php.
What happens
When a completed submission resumes a task, resumeTarget() first resolves the exact branch token the branch-scoped handle named, via parkedTokenById(). That path is correct and covers the normal case. When the named token is no longer parked (read as a loop re-entry: the flow re-parked the same step with a fresh token while the reopened submission still names the original, now consumed one), it falls back to parkedTokenAtNode(), which returns the lowest-id parked token on that node.
parkedTokenAtNode() is documented to pick the lowest-id token when several are parked on the node. So if two sibling branches are parked on the same node at the same time (a parallel split whose branches both wait at one shared form step), and the named token was consumed by a loop re-entry, the fallback can resume the wrong sibling: the submitting party's result is applied to, and stored on, another branch.
Why it is not reachable on shipped config
- The exact-id path (parkedTokenById) handles every normal resume; the ambiguity lives only in the fallback.
- The fallback only triggers when the named token is gone, that is, a loop that re-enters the same step.
- Triggering the wrong-sibling resume needs both at once: two parallel branches parked on the same webform node, and a loop back to that node that consumes the originally named token.
- No shipped example workflow combines parallel same-node webform parking with a loop back to that node, so the fallback never has a sibling to confuse.
Suggested fix
Make the fallback branch-aware instead of node-wide. The consumed token still exists as an entity, so its branch lineage is resolvable. Before falling back to parkedTokenAtNode(), resolve the parked token in the consumed token's own chain:
- currentChain($instance, $token_id) to follow the branch lineage forward, then parkedTokenInChain($instance, $chain) to get the token parked on that branch.
- Only when chain resolution yields nothing (a genuine fork, or an unresolvable lineage) fall back to parkedTokenAtNode() as today.
Both helpers already exist on InteractionResolver and are used by nextBranchToken() to scope the post-resume return link, so this makes the resume target consistent with the return scoping.
Test to add
A functional (real HTTP) test: a workflow that forks two branches onto one shared webform step, with a loop that re-enters that step so the first branch's named token is consumed; submit against the reopened handle and assert the resume lands on the correct branch (its result variable is set) and the sibling branch is left untouched.
Issue fork orchestra-3608540
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedOpened MR !291 against 1.x with the branch-aware fallback and a kernel test.
The resume fallback now follows the consumed token's interaction chain to the branch's own re-parked token, and only drops to the node when the chain has not advanced (a non-interactive step) or is unresolvable, so the plain single-branch loop re-entry is unchanged. The added test forks two branches onto one shared interactive step, loops one back, and asserts the party's own branch is resumed while the sibling stays parked; it fails without the fix and passes with it. Local run: OrchestraInteractionHandlerTest green (15 tests), phpcs and cspell clean. Setting to Needs review pending CI.
Comment #5
mably commented