{"record":{"id":"9471d4a120eb3572","repo":"gastownhall/beads","slug":"failed-to-update-encrypted-password-for-peer-s","errorCode":null,"errorMessage":"failed to update encrypted password for peer %s: %w","messagePattern":"failed to update encrypted password for peer (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/credentials.go","lineNumber":190,"sourceCode":"\t\t\t// Can't decrypt with old key — skip (may already use a different scheme)\n\t\t\tcontinue\n\t\t}\n\t\ttoMigrate = append(toMigrate, migrationEntry{name: name, plaintext: plaintext})\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn fmt.Errorf(\"failed to iterate peers for migration: %w\", err)\n\t}\n\n\t// Re-encrypt each password with the new key\n\tfor _, entry := range toMigrate {\n\t\tencrypted, err := encryptWithKey(entry.plaintext, newKey)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to re-encrypt password for peer %s: %w\", entry.name, err)\n\t\t}\n\t\tif _, err := s.execContext(ctx, `\n\t\t\tUPDATE federation_peers SET password_encrypted = ? WHERE name = ?\n\t\t`, encrypted, entry.name); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to update encrypted password for peer %s: %w\", entry.name, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// encryptWithKey encrypts plaintext using AES-GCM with the given key.\nfunc encryptWithKey(plaintext string, key []byte) ([]byte, error) {\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgcm, err := cipher.NewGCM(block)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnonce := make([]byte, gcm.NonceSize())\n\tif _, err := io.ReadFull(rand.Reader, nonce); err != nil {","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/credentials.go#L172-L208","documentation":"After re-encrypting each peer password with the new key, migrateCredentialKeys persists it with UPDATE federation_peers SET password_encrypted = ? WHERE name = ?. This error wraps a failure of that UPDATE for the named peer. The migration aborts so the database never ends up with some peers on the new key and some on the old key under a single saved key file.","triggerScenarios":"s.execContext with the UPDATE statement fails during migration: database connection dropped or context canceled/timed out mid-loop, write lock contention with another bd process or dolt-sql-server, table read-only, or a Dolt transaction/commit error on federation_peers.","commonSituations":"Concurrent bd commands or an external dolt-sql-server holding the write lock during `bd` open; network blip to a remote Dolt server partway through migrating several peers; context deadline exceeded on large peer tables.","solutions":["Retry the operation — since the key file is only written after successful migration, the next open re-runs migration from scratch (old ciphertexts are idempotently re-encrypted)","Check for lock contention: stop concurrent bd processes/dolt-sql-server instances, then retry","Verify the database accepts writes and the context deadline is adequate; raise timeouts if the peer table is large","Inspect the wrapped driver error for the exact SQL failure and fix that root cause"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check writability of the table before migration-heavy operations\n_, err := db.ExecContext(ctx, \"SELECT 1 FROM federation_peers LIMIT 1\")\nif err != nil { return fmt.Errorf(\"federation_peers unreadable: %w\", err) }","typeGuard":null,"tryCatchPattern":"err := bdCmd()\nif err != nil && strings.Contains(err.Error(), \"failed to update encrypted password for peer\") {\n    // safe to retry: UPDATE is re-applied from intact old ciphertext on next migration\n    return retryWithBackoff(bdCmd, 3)\n}","preventionTips":["Serialize bd operations that touch federation_peers across processes and servers","Ensure the Dolt server accepts writes (not read-only) before upgrades","Use adequate context timeouts for many-peer migrations"],"tags":["database","sql","migration","dolt","update-failed"],"backgroundTag":"sql-update-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}