Fix off-by-one in RPC result attribution - #1
Draft
plan9better wants to merge 1 commit into
Draft
Conversation
configure() prepends "configure terminal" to the payload, so the device returns one more result than the caller's command list. summary() zipped those results against the patch commands from index 0, so every command was reported with the previous command's result: failures were logged against the following command, and the first real command absorbed the prologue's empty result and always printed msg="ok". Drop the prologue's entry in configure() so the returned results align 1:1 with the commands, and bail in summary() on a length mismatch rather than let zip() silently truncate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Problem
configure()prepends"configure terminal"to the payload, so the device returns N+1 results for an N-line patch.summary()zipped those results against the patch commands starting at index 0, so every command was reported with the previous command's result.Two visible consequences:
msg="ok", so a failed command can be reported as successful.zip()silently truncates on the length mismatch, which is why this never surfaced as an error.Impact
Real log from a failing run against a switch, with a 14-line patch:
This reads as nonsense:
exitcannot produce-3004in interface mode, andinterface eth-0-3cannot produce a lacp-mode error. Shift by one and it resolves exactly:exitno channel-group 3(invalid syntax — the real bug, in the patch)interface eth-0-3port-channel 3 lacp-mode dynamicexitmlag 3The misattribution actively obscured the root cause:
no channel-group 3was loggedmsg="ok"while it was in fact the command that failed and stalled the whole patch.Fix
configure()drops the prologue's result entry, so what it returns aligns 1:1 withcommands. The prepend stays an implementation detail of the function that introduced it.summary()bails on a length mismatch instead of lettingzip()truncate silently, so this class of misalignment fails loudly.Testing
cargo buildclean. Pre-existingcargo fmtdiff and 3 clippy warnings are untouched on master and left alone to keep the diff reviewable.Verified by hand against the log above: with the prologue dropped, all 14 results line up with their commands and each error lands on a command that can actually produce it.
🤖 Generated with Claude Code