mattermost-community/focalboard · error
cannot get migration state: %w
Error message
cannot get migration state: %w
What it means
Wraparound error in SQLStore.RunUniqueIDsMigration (server/services/store/sqlstore/data_migrations.go:75). Before running the unique-IDs data migration, the store reads the UniqueIDsMigrationKey system setting to check whether the migration already completed. If GetSystemSetting itself returns an error (not merely an empty value), this error is wrapped so the caller (runMigrationSequence) knows migration state lookup failed.
Source
Thrown at server/services/store/sqlstore/data_migrations.go:75
rows, err := s.getQueryBuilder(db).
Select(blocksFields...).
From(s.tablePrefix + "blocks").
Where(fmt.Sprintf("id IN (%s)", subquery)).
Query()
if err != nil {
s.logger.Error(`getBlocksWithSameID ERROR`, mlog.Err(err))
return nil, err
}
defer s.CloseRows(rows)
return s.blocksFromRows(rows)
}
func (s *SQLStore) RunUniqueIDsMigration() error {
setting, err := s.GetSystemSetting(UniqueIDsMigrationKey)
if err != nil {
return fmt.Errorf("cannot get migration state: %w", err)
}
// If the migration is already completed, do not run it again.
if hasAlreadyRun, _ := strconv.ParseBool(setting); hasAlreadyRun {
return nil
}
s.logger.Debug("Running Unique IDs migration")
tx, txErr := s.db.BeginTx(context.Background(), nil)
if txErr != nil {
return txErr
}
blocks, err := s.getBlocksWithSameID(tx)
if err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
s.logger.Error("Unique IDs transaction rollback error", mlog.Err(rollbackErr), mlog.String("methodName", "getBlocksWithSameID"))View on GitHub (pinned to a84bbb65e3)
Solutions
- Check the wrapped %w cause for the exact DB error (connection, permissions, missing table).
- Verify the SystemSettings table exists and the DB user has SELECT rights.
- Check DB connectivity and retry server start; the migration runs only once so a healthy retry is safe.
- Fix schema initialization failures before the app starts migrations.
- If the setting value is empty/absent, note the store tolerates it (ParseBool error is ignored) — only read failures produce this error.
Example fix
// before
err := store.RunUniqueIDsMigration()
if err != nil {
log.Fatal(err)
}
// after
err := store.RunUniqueIDsMigration()
if err != nil {
if isTransientDBError(errors.Unwrap(err)) {
log.Println("transient DB error, retrying migration", err)
time.Sleep(time.Second)
err = store.RunUniqueIDsMigration()
}
if err != nil {
log.Fatal(err)
}
} Defensive patterns
Strategy: retry
Validate before calling
if err := db.Ping(); err != nil { return fmt.Errorf("db unavailable, defer migrations: %w", err) } Type guard
func isMigrationStateError(err error) bool {
return err != nil && strings.Contains(err.Error(), "cannot get migration state")
} Try / catch
err := store.RunUniqueIDsMigration()
if err != nil {
if isMigrationStateError(err) && isTransient(errors.Unwrap(err)) {
time.Sleep(backoff)
err = store.RunUniqueIDsMigration()
}
if err != nil { log.Fatal(err) }
} Prevention
- Verify schema initialization completed before running migrations
- Ensure the app DB user can SELECT from SystemSettings
- Start only one instance against a DB at a time for migrations
- Retry on transient DB errors; the migration flag prevents double-run
When it happens
Trigger: Calling RunUniqueIDsMigration when the system settings read fails: database connection error, corrupt/locked SystemSettings table, query timeout, or missing table due to incomplete schema initialization.
Common situations: Fresh installs where schema init failed; DB user lacking SELECT permission on the SystemSettings table; transient DB outage during server startup when runMigrationSequence executes; proxy/pool timeouts on large settings rows.
Related errors
- cannot get blocks with same ID: %w
- cannot replace blockID %s: %w
- cannot mark migration as completed: %w
- cannot commit unique IDs transaction: %w
- cannot commit category UUIDs transaction: %w
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/a13ffdbe1f2cd811.
Report an issue: GitHub.