gastownhall/beads · warning
delete staging branch: %w
Error message
delete staging branch: %w
What it means
Wraps an error from deleteFederationStagingBranch, which drops a temporary staging branch created during filtered federation push/pull. Cleanup runs in a deferred path after a failed or completed operation, and the error is accumulated into cleanupErr via errors.Join so earlier failures are preserved. It means the Dolt CALL DOLT_BRANCH('-D', ...) (or equivalent) on the cleanup connection failed, potentially leaving a stale staging branch behind.
Source
Thrown at internal/storage/dolt/federation.go:579
// fresh, uncanceled, bounded connection. Errors are joined; a non-nil result is
// wrapped by the caller with the "federation filter: cleanup" context.
func cleanupFilteredStaging(ctx context.Context, db *sql.DB, conn *sql.Conn, sourceBranch, stagingBranch string) error {
cleanupCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), federationStagingCleanupTimeout)
defer cancel()
var cleanupErr error
if err := conn.Close(); err != nil {
cleanupErr = errors.Join(cleanupErr, fmt.Errorf("discard operation connection: %w", err))
}
cleanupConn, err := db.Conn(cleanupCtx)
if err != nil {
cleanupErr = errors.Join(cleanupErr, fmt.Errorf("acquire cleanup connection: %w", err))
} else {
defer cleanupConn.Close()
if err := schema.DrainCall(cleanupCtx, cleanupConn, "CALL DOLT_CHECKOUT(?)", sourceBranch); err != nil {
cleanupErr = errors.Join(cleanupErr, fmt.Errorf("restore branch %s: %w", sourceBranch, err))
}
if err := deleteFederationStagingBranch(cleanupCtx, cleanupConn, stagingBranch); err != nil {
cleanupErr = errors.Join(cleanupErr, fmt.Errorf("delete staging branch: %w", err))
}
}
return cleanupErr
}
func deleteFederationStagingBranch(ctx context.Context, conn *sql.Conn, stagingBranch string) error {
err := schema.DrainCall(ctx, conn, "CALL DOLT_BRANCH('-Df', ?)", stagingBranch)
var mysqlErr *mysql.MySQLError
// Dolt reports a missing branch as generic error 1105; match the message as
// a case-insensitive substring (as RemoteRefUnavailableErr does) because
// Dolt may append the branch/ref name to this class of error.
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1105 &&
strings.Contains(strings.ToLower(mysqlErr.Message), "branch not found") {
return nil
}
return err
}
View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the operation; check for and manually drop leftover staging branches with CALL DOLT_BRANCH('-D', '<staging-branch>')
- Inspect the wrapped inner error (errors.Join output) to find the root Dolt cause before retrying
- Ensure no other connection/session holds the staging branch checked out during cleanup
- Verify the cleanup connection (cleanupConn) is still alive and cleanupCtx has not been canceled
Example fix
// before
if err := deleteFederationStagingBranch(cleanupCtx, cleanupConn, stagingBranch); err != nil {
cleanupErr = errors.Join(cleanupErr, fmt.Errorf("delete staging branch: %w", err))
}
// after
if err := deleteFederationStagingBranch(cleanupCtx, cleanupConn, stagingBranch); err != nil {
// Idempotent retry: a missing branch on cleanup is harmless
var doltErr *mysql.MySQLError
if !errors.As(err, &doltErr) || doltErr.Number != errno.ErrNoSuchTable {
cleanupErr = errors.Join(cleanupErr, fmt.Errorf("delete staging branch: %w", err))
}
} Defensive patterns
Strategy: try-catch
Try / catch
result, err := stageFilteredBranch(ctx, ...)
if err != nil {
// cleanup errors are joined; check for staging branch leftovers
var joined interface{ Unwrap() []error }
if errors.As(err, &joined) { /* log each joined cleanup error */ }
// then manually: CALL DOLT_BRANCH('-D', stagingBranch) to reclaim
} Prevention
- Avoid multiple sessions on the same staging branch
- Set generous cleanupCtx deadlines
- Periodically sweep orphaned *staging* branches
When it happens
Trigger: cleanupFilteredStaging's deferred/else path calls deleteFederationStagingBranch and the underlying SQL delete of the staging branch fails (connection lost, branch checked out in another session, permissions, or the branch name doesn't exist).
Common situations: Network drop or server restart mid-operation; another Dolt session is checked out on the staging branch so DOLT_BRANCH -D refuses; database was recreated so the branch no longer exists; partially created staging branch from an earlier crashed run.
Related errors
- ErrExec
- database not available: %w
- not using Dolt backend (configured backend %q)
- no storage backend is open
- storage backend does not support backup operations
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4943bac65e147bf6.
Report an issue: GitHub.