{"record":{"id":"53ecfc457f2d828a","repo":"gastownhall/beads","slug":"list-federation-peers-w","errorCode":null,"errorMessage":"list federation peers: %w","messagePattern":"list federation peers: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/federation.go","lineNumber":100,"sourceCode":"\n\tif username.Valid {\n\t\trow.Peer.Username = username.String\n\t}\n\tif lastSync.Valid {\n\t\trow.Peer.LastSync = &lastSync.Time\n\t}\n\n\treturn &row, nil\n}\n\n// ListFederationPeersInTx returns all configured federation peer rows.\nfunc ListFederationPeersInTx(ctx context.Context, tx *sql.Tx) ([]*FederationPeerRow, error) {\n\trows, err := tx.QueryContext(ctx, `\n\t\tSELECT name, remote_url, username, password_encrypted, sovereignty, last_sync, created_at, updated_at\n\t\tFROM federation_peers ORDER BY name\n\t`)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"list federation peers: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tvar peers []*FederationPeerRow\n\tfor rows.Next() {\n\t\tvar row FederationPeerRow\n\t\tvar lastSync sql.NullTime\n\t\tvar username sql.NullString\n\n\t\tif err := rows.Scan(\n\t\t\t&row.Peer.Name, &row.Peer.RemoteURL, &username, &row.EncryptedPwd,\n\t\t\t&row.Peer.Sovereignty, &lastSync, &row.Peer.CreatedAt, &row.Peer.UpdatedAt,\n\t\t); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"scan federation peer: %w\", err)\n\t\t}\n\n\t\tif username.Valid {\n\t\t\trow.Peer.Username = username.String","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/federation.go#L82-L118","documentation":"ListFederationPeersInTx failed while querying federation_peers; the driver error is wrapped as \"list federation peers\". This is a database-level failure (missing table, connection, schema), not an empty result. An empty table returns an empty slice with nil error.","triggerScenarios":"tx.QueryContext on federation_peers returns a driver error: table missing (migration not run), connection refused/reset, or schema mismatch.","commonSituations":"Fresh database before migrations; Dolt server down; running a newer binary against an older schema where federation_peers doesn't exist.","solutions":["Read the wrapped driver error to identify the root cause","Run pending schema migrations to create federation_peers","Retry if the error is transient (connection reset)","Confirm you are connected to the intended database"],"exampleFix":"// before\npeers, err := issueops.ListFederationPeersInTx(ctx, tx) // fails: table not found\n// after\nif err := migrate(ctx, db); err != nil { // ensure federation_peers exists\n    return err\n}\npeers, err := issueops.ListFederationPeersInTx(ctx, tx)","handlingStrategy":"retry","validationCode":"// ensure federation_peers exists before listing\nif err := migrate(ctx, db); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"var peers []*issueops.FederationPeerRow\nvar err error\nfor i := 0; i < 3; i++ {\n    peers, err = issueops.ListFederationPeersInTx(ctx, tx)\n    if err == nil || errors.Is(ctx.Err(), context.Canceled) {\n        break\n    }\n    time.Sleep(time.Duration(1<<i) * 100 * time.Millisecond) // transient-error backoff\n}\nif err != nil {\n    return fmt.Errorf(\"list peers: %w\", err)\n}","preventionTips":["Retry transient driver errors with backoff","Run migrations on startup so tables always exist","Distinguish empty results (nil error) from query failures"],"tags":["database","sql","federation","go"],"backgroundTag":"database-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}