Conversation
The resubmit half of the node ID collision test pinned the behaviour memoized resubmit had in argoproj#16883, where a failed pod node was copied into the new workflow as Pending. argoproj#16938 rewrote memoized resubmit to plan the same reset as a retry, which deletes a failed execution node so the controller creates it afresh. Neither branch contained the other, so both were green on their own and main went red on the merge. Keep the coverage of carrying a widened node ID across the rename by memoizing a workflow whose colliding leaf succeeded, which resubmit still keeps, and cover the delete path in its own test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SHgquNL1W9UC2xz3R5cmXN Signed-off-by: Alan Clucas <alan@clucas.org>
Resubmitting gives the workflow a new name, and a node ID is a hash of the node name, which starts with the workflow name, so the rename rehashes the whole graph. Collisions the original workflow did not have can appear, and the mapping used the 32-bit ID unconditionally: the node that lost the race was dropped from the new status, or, worse, a reference to a node the reset plan deleted could land on the ID of one that was kept and survive pruning as a false edge. Work the IDs out up front, in node name order so the result does not depend on map iteration order, widening a name whose 32-bit slot has gone to another one just as the controller does when it creates a node. Deleted nodes are mapped too, so their references cannot alias a node that is kept. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SHgquNL1W9UC2xz3R5cmXN Signed-off-by: Alan Clucas <alan@clucas.org>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #17028 +/- ##
==========================================
+ Coverage 44.75% 44.77% +0.02%
==========================================
Files 575 575
Lines 39591 39610 +19
==========================================
+ Hits 17717 17734 +17
- Misses 21872 21874 +2
Partials 2 2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: argoproj/argo-workflows/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughMemoized resubmission now precomputes unique node IDs after renaming. It widens colliding IDs to 64-bit values, rejects collisions at both widths, and drops references to nodes absent from status. New tests cover rename collisions and reset-plan deletions. ChangesMemoized resubmit node ID mapping
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
make pre-commit -Bmake feature-new)Follow-up to #16883, which fixed the controller side of the same problem.
Stacked on #17027, which unbreaks
main; the first commit here is that PR. Rebasing once it merges leaves one commit.Motivation
#16883 made the controller tolerate node ID hash collisions: a name that loses the 32-bit slot to another name is stored under the widened
NodeID64instead, andResolveNodelooks in both places. Memoized resubmit was left alone, and it is the one place that rehashes an entire existing graph.Resubmit gives the workflow a new name. A node ID is a hash of the node name, which starts with the workflow name, so every ID changes: a collision the original workflow had dissolves, and one it never had can appear.
convertNodeIDreturnednewWf.NodeID(name)unconditionally, so under a new collision:applyResetPlandoes and leaves a false edge to an unrelated node.Rare, but a resubmit picks a fresh random name each time, so it is reachable by chance rather than by anything the user did.
Modifications
convertNodeIDis replaced bynewNodeIDs, which works the whole mapping out before the plan is applied:applyResetPlanhas;NodeID64, matching what the controller does when it creates a node, soResolveNodefinds it afterwards;initializeNoderefuses it.Verification
Two unit tests.
TestNewNodeIDsWidensACollisionMadeByTheRenameuses a pair ofwithItemssibling names that do not collide under the old workflow name but do under the new one (found by search, since the hash is fixed), and checks that nothing is lost and both nodes are resolvable by name afterwards.TestNewNodeIDsKeepsDeletedNodesOutOfTheWaychecks every node is mapped to a distinct ID. An end-to-end test throughFormulateResubmitWorkflowis not possible: it picks the new name at random, so a collision cannot be forced.go test ./workflow/util/...and the resubmit/retry tests inworkflow/controllerandserver/workflowpass;golangci-lint run ./workflow/util/...is clean. Fullmake pre-commit -Bnot run — codegen needs the checkout at its$GOPATHpath and this was built in a worktree; nothing here is generated.Documentation
Not needed, no user-visible behaviour or configuration changes.
AI
Claude Code (Claude Opus 5) found the gap while analysing the CI failure fixed in #17027, and wrote the change, the tests and the commit message. The colliding name pair was found by brute-force search over FNV-1a 32.
Summary by CodeRabbit