PR #59 surfaced a recurring pattern: mutable "pending" state fields on panel structs (pendingPath, pendingName, etc.) are set on the applicable code path but not explicitly cleared on other branches. This creates stale-state bugs where a value set in one interaction leaks into a later, unrelated interaction.
Example from PR #59 review:
In gitinfo, p.pendingPath was set inside if item.kind == kindWorktree in both handleMouseRightClick and doAction, but no else branch cleared it for non-worktree items. A stale pendingPath from a prior worktree action could survive across modal round-trips and corrupt a subsequent non-worktree action.
Fixes applied in PR #59:
- handleMouseRightClick: added
else { p.pendingPath = "" } for non-worktree items
- doAction first-use confirm branch: added
else { p.pendingPath = "" } for non-worktree items
Convention to codify:
When a panel sets a mutable op-state field on one branch of an if/switch, add an explicit zero-assignment on all other branches — even when the value "shouldn't matter" on those paths. This makes the invariant explicit and prevents future regressions as new code paths are added.
Document this in the conventions guide alongside the existing op-state clearing pattern in handleModalResult.
PR #59 surfaced a recurring pattern: mutable "pending" state fields on panel structs (pendingPath, pendingName, etc.) are set on the applicable code path but not explicitly cleared on other branches. This creates stale-state bugs where a value set in one interaction leaks into a later, unrelated interaction.
Example from PR #59 review:
In gitinfo, p.pendingPath was set inside
if item.kind == kindWorktreein both handleMouseRightClick and doAction, but noelsebranch cleared it for non-worktree items. A stale pendingPath from a prior worktree action could survive across modal round-trips and corrupt a subsequent non-worktree action.Fixes applied in PR #59:
else { p.pendingPath = "" }for non-worktree itemselse { p.pendingPath = "" }for non-worktree itemsConvention to codify:
When a panel sets a mutable op-state field on one branch of an
if/switch, add an explicit zero-assignment on all other branches — even when the value "shouldn't matter" on those paths. This makes the invariant explicit and prevents future regressions as new code paths are added.Document this in the conventions guide alongside the existing op-state clearing pattern in handleModalResult.