gastownhall/beads · error

failed to scan peer for migration: %w

Error message

failed to scan peer for migration: %w

What it means

During credential key migration, migrateCredentialKeys scans each federation_peers row into (name, password_encrypted) with rows.Scan. This error wraps a scan failure, meaning a row's data could not be read into the expected Go types. Because the columns are queried by name from bd's own schema, this almost always indicates schema drift or driver-level data corruption rather than application logic.

Source

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

		WHERE password_encrypted IS NOT NULL AND LENGTH(password_encrypted) > 0
	`)
	if err != nil {
		// Table may not exist yet (fresh install) — not an error
		return nil
	}
	defer rows.Close()

	type migrationEntry struct {
		name      string
		plaintext string
	}

	var toMigrate []migrationEntry
	for rows.Next() {
		var name string
		var encrypted []byte
		if err := rows.Scan(&name, &encrypted); err != nil {
			return fmt.Errorf("failed to scan peer for migration: %w", err)
		}

		// Decrypt with old key
		plaintext, err := decryptWithKey(encrypted, oldKey)
		if err != nil {
			// Can't decrypt with old key — skip (may already use a different scheme)
			continue
		}
		toMigrate = append(toMigrate, migrationEntry{name: name, plaintext: plaintext})
	}
	if err := rows.Err(); err != nil {
		return fmt.Errorf("failed to iterate peers for migration: %w", err)
	}

	// Re-encrypt each password with the new key
	for _, entry := range toMigrate {
		encrypted, err := encryptWithKey(entry.plaintext, newKey)
		if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the federation_peers schema and rows: dolt sql -q "SELECT name, password_encrypted FROM federation_peers" to find malformed rows
  2. Restore the expected schema (name NOT NULL, password_encrypted VARBINARY) or fix/re-insert the offending row
  3. Re-run the bd command; if the failure was a transient connection issue, migration retries next open while no key file exists
  4. If a specific peer row is corrupt and unneeded, delete that peer with `bd` peer-removal tooling or a targeted DELETE, then retry
Defensive patterns

Strategy: validation

Validate before calling

// Check schema integrity before operating on federation_peers
cols, err := db.Query("SHOW COLUMNS FROM federation_peers")
// verify expected: name (NOT NULL, string), password_encrypted (VARBINARY)
if err != nil { return err }

Prevention

When it happens

Trigger: rows.Scan(&name, &encrypted) fails while iterating federation_peers during initCredentialKey migration: the row contains NULL in a non-NULL-scanned column (password_encrypted is filtered by the WHERE clause, so this mainly means name is NULL), the column types differ from the expected schema (schema drift/manual DDL), or the connection/driver returns a malformed row mid-stream.

Common situations: Manually altered federation_peers schema (columns reordered or types changed by hand-edited SQL); partial/failed Dolt schema migration leaving rows of a different shape; a connection error surfacing as a scan failure on a long-lived server connection.

Related errors


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