gastownhall/beads · error

get federation peer: %w

Error message

get federation peer: %w

What it means

The SELECT of the federation peer row failed at the SQL level (not ErrNoRows); the driver error is wrapped as "get federation peer". This signals a database-side problem such as a missing table, schema mismatch, or connection failure, not an absent peer. Check the wrapped driver error.

Source

Thrown at internal/storage/issueops/federation.go:80

// Returns storage.ErrNotFound (wrapped) if the peer does not exist.
func GetFederationPeerInTx(ctx context.Context, tx *sql.Tx, name string) (*FederationPeerRow, error) {
	var row FederationPeerRow
	var lastSync sql.NullTime
	var username sql.NullString

	err := tx.QueryRowContext(ctx, `
		SELECT name, remote_url, username, password_encrypted, sovereignty, last_sync, created_at, updated_at
		FROM federation_peers WHERE name = ?
	`, name).Scan(
		&row.Peer.Name, &row.Peer.RemoteURL, &username, &row.EncryptedPwd,
		&row.Peer.Sovereignty, &lastSync, &row.Peer.CreatedAt, &row.Peer.UpdatedAt,
	)

	if err == sql.ErrNoRows {
		return nil, fmt.Errorf("%w: federation peer %s", storage.ErrNotFound, name)
	}
	if err != nil {
		return nil, fmt.Errorf("get federation peer: %w", err)
	}

	if username.Valid {
		row.Peer.Username = username.String
	}
	if lastSync.Valid {
		row.Peer.LastSync = &lastSync.Time
	}

	return &row, nil
}

// ListFederationPeersInTx returns all configured federation peer rows.
func ListFederationPeersInTx(ctx context.Context, tx *sql.Tx) ([]*FederationPeerRow, error) {
	rows, err := tx.QueryContext(ctx, `
		SELECT name, remote_url, username, password_encrypted, sovereignty, last_sync, created_at, updated_at
		FROM federation_peers ORDER BY name
	`)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped driver error to identify the root cause
  2. Run pending schema migrations so federation_peers has the expected columns
  3. Retry the transaction if the error was transient
  4. Verify the transaction is still active and not rolled back

Example fix

// before
peer, err := issueops.GetFederationPeerInTx(ctx, tx, name) // fails: unknown column sovereignty
// after
if err := migrate(ctx, db); err != nil { // bring schema current
    return err
}
peer, err := issueops.GetFederationPeerInTx(ctx, tx, name)
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure schema is current before reading
if err := migrate(ctx, db); err != nil {
    return err
}

Try / catch

peer, err := issueops.GetFederationPeerInTx(ctx, tx, name)
if err != nil && !errors.Is(err, storage.ErrNotFound) {
    log.Printf("get federation peer %s failed: %v", name, err)
    return fmt.Errorf("lookup peer %s: %w", name, err)
}

Prevention

When it happens

Trigger: tx.QueryContext/Scan on federation_peers returns a driver error: table missing, column mismatch, connection dropped, or transaction aborted.

Common situations: Older database without federation_peers (migration not run); Dolt server restarted mid-transaction; column added/renamed in a version change.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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