gastownhall/beads · error

failed to list federation peers: %w

Error message

failed to list federation peers: %w

What it means

ListFederationPeers runs a SELECT over the federation_peers table and returns all configured peers. This error wraps any failure executing that query against the Dolt database — the table is missing, the connection to the SQL server is down, or the query is cancelled. The library throws it so callers get a descriptive error instead of a raw driver error.

Source

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

			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)
		}
	}

	return &peer, nil
}

// ListFederationPeers returns all configured federation peers.
func (s *DoltStore) ListFederationPeers(ctx context.Context) ([]*storage.FederationPeer, error) {
	rows, err := s.queryContext(ctx, `
		SELECT name, remote_url, username, password_encrypted, sovereignty, last_sync, created_at, updated_at
		FROM federation_peers ORDER BY name
	`)
	if err != nil {
		return nil, fmt.Errorf("failed to list federation peers: %w", err)
	}
	defer rows.Close()

	var peers []*storage.FederationPeer
	for rows.Next() {
		var peer storage.FederationPeer
		var encryptedPwd []byte
		var lastSync sql.NullTime
		var username sql.NullString

		if err := rows.Scan(&peer.Name, &peer.RemoteURL, &username, &encryptedPwd, &peer.Sovereignty, &lastSync, &peer.CreatedAt, &peer.UpdatedAt); err != nil {
			return nil, fmt.Errorf("failed to scan federation peer: %w", err)
		}

		if username.Valid {
			peer.Username = username.String
		}
		if lastSync.Valid {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the database is reachable: restart the dolt-sql-server or re-open the embedded store.
  2. Ensure the schema is up to date — run bd's init/migration so federation_peers exists (SELECT * FROM federation_peers LIMIT 1 to test).
  3. Check ctx cancellation: pass context.Background() or a non-expired context if this fires spuriously.
  4. If the table is truly absent on a fresh install, treat it as an empty peer list rather than an error in your tooling.

Example fix

// before
peers, err := store.ListFederationPeers(ctx) // failed to list federation peers: ...table doesn't exist
// after: initialize schema first
if err := store.Init(ctx); err != nil { return err }
peers, err := store.ListFederationPeers(ctx)
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check table accessibility
row := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM federation_peers")
var n int
if err := row.Scan(&n); err != nil { /* table missing or DB down */ }

Try / catch

peers, err := store.ListFederationPeers(ctx)
if err != nil {
    var notFound *storage.ErrNotFound
    log.Printf("listing peers failed (empty or unreachable DB?): %v", err)
    peers = nil
}

Prevention

When it happens

Trigger: Calling ListFederationPeers when the federation_peers table doesn't exist yet (fresh DB before any AddFederationPeer/`bd init` migration ran), the dolt-sql-server connection has been dropped, or ctx is cancelled mid-query.

Common situations: Running `bd federation` style listing against a server-mode Dolt instance that was restarted; pointing bd at a database created by an older beads version lacking the table; network drops to a remote dolt-sql-server.

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/6157c32b0142351d. Report an issue: GitHub.