gastownhall/beads · error

failed to remove federation peer: %w

Error message

failed to remove federation peer: %w

What it means

RemoveFederationPeer deletes a peer row (and its encrypted credentials) from federation_peers via DELETE. This error wraps the SQL exec failure. Note the function is tolerant of the peer not existing (0 rows affected is fine); this error only fires when the DELETE statement itself fails.

Source

Thrown at internal/storage/dolt/credentials.go:413

				return nil, fmt.Errorf("failed to initialize credential key: %w", err)
			}
			peer.Password, err = s.decryptPassword(encryptedPwd)
			if err != nil {
				return nil, fmt.Errorf("failed to decrypt password: %w", err)
			}
		}

		peers = append(peers, &peer)
	}

	return peers, rows.Err()
}

// RemoveFederationPeer removes a federation peer and its credentials.
func (s *DoltStore) RemoveFederationPeer(ctx context.Context, name string) error {
	result, err := s.execContext(ctx, "DELETE FROM federation_peers WHERE name = ?", name)
	if err != nil {
		return fmt.Errorf("failed to remove federation peer: %w", err)
	}

	rows, _ := result.RowsAffected() // Best effort: rows affected is used only for logging
	if rows == 0 {
		// Peer not in credentials table, but might still be a Dolt remote
		// Continue to try removing the remote
	}

	// Also remove the Dolt remote (best-effort)
	_ = s.RemoveRemote(ctx, name) // Best effort cleanup before re-adding remote

	return nil
}

// updatePeerLastSync updates the last sync time for a peer.
func (s *DoltStore) updatePeerLastSync(ctx context.Context, name string) error {
	_, err := s.execContext(ctx, "UPDATE federation_peers SET last_sync = CURRENT_TIMESTAMP WHERE name = ?", name)
	return wrapExecError("update peer last sync", err)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify DB connectivity: reconnect the store or restart dolt-sql-server, then retry the removal.
  2. Ensure the federation_peers table exists (run bd init/migration).
  3. Check for lock contention or read-only mode on the Dolt database and retry after resolving.
  4. If the peer already doesn't exist, the removal is effectively a no-op — you can treat a 'table not found' as success in cleanup code.

Example fix

// before
err := store.RemoveFederationPeer(ctx, "old-peer") // connection refused
// after: reopen the store first
store, err = dolt.OpenStore(dbPath)
if err != nil { return err }
err = store.RemoveFederationPeer(ctx, "old-peer")
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm DB is writable/reachable before deleting
if err := db.PingContext(ctx); err != nil { /* reconnect first */ }

Try / catch

err := store.RemoveFederationPeer(ctx, name)
if err != nil {
    // table may not exist or DB may be down; treat missing-table as success for cleanup paths
    if !strings.Contains(err.Error(), "doesn't exist") { return err }
}

Prevention

When it happens

Trigger: Calling RemoveFederationPeer when the database connection is down, the federation_peers table doesn't exist, the context is cancelled, or the server rejects the write (read-only replica, permissions, lock timeout).

Common situations: dolt-sql-server restarted or unreachable mid-session; operating on a DB from an older beads version without the table; concurrent Dolt transactions holding locks; stale credentials after a server-mode connection drop.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/0d4fce482c76b589. Report an issue: GitHub.