fix(finish): attach the reconcile steer to the out-of-date-with-base merge failure, still non-retryable (#456) #475
No reviewers
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea!475
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-456-madt-finishmerge-masks-real-gitea-merge-errors-as"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes #456. The three original asks landed in PR #463 (verbatim surfacing, non-retryable classification, post-5xx landed re-check). This is the one refinement decided on 2026-09-08: the out-of-date-with-base failure keeps its verbatim Gitea body and its non-retryable status, and now also carries the copy-pasteable update-branch-and-remerge block, matching the behind-base 405 path.
Changes:
internal/gitea/client_errors.go: newIsMergeOutOfDatepredicate, a strict subset ofIsMergeNonRetryable(405 plus the "out-of-date with the base branch" body, case-insensitive).internal/service/workflow/merge.go: after the retry loop, an out-of-datelastErrreturnsmerge failed: <verbatim body>followed byReconcileSteer(prNum, rp). Nothing-to-merge and no-signing-key stay bare. No retry, no auto-update.TestIsMergeOutOfDate(match set, status gating, subset-of-non-retryable invariant);TestMergeWithRetryNonRetryable_OutOfDatenow asserts the steer is present, and the AlreadyIncluded and NoSigningKey tests assert it is absent. The shared helper returns the message so callers can assert on it.docs/architecture/error-handling.md: the non-retryable table and prose describe the steer on the out-of-date row.Gate:
./scripts/gate.shfull run passes (go-version, build, gofmt, vet, gofix, modtidy, licenses, hook-tests, adr-check, test-race, staticcheck, govulncheck, gosec, modernize, docs-verify, cross-compile, mcp-conformance).Evidence for the earlier asks, for the record:
IsMergeNonRetryableand the verbatimmerge failed: %wwrap atinternal/service/workflow/merge.go(post-loop), the landed re-check on 5xx insideMergeWithRetry, all pinned byTestMergeWithRetry5xxAlreadyMerged,TestMergeWithRetry5xxNotMergeableSurfacedVerbatim, and the threeTestMergeWithRetryNonRetryable_*tests.Closes #456