mattermost-community/focalboard · error

failed to insert board

Error message

failed to insert board %s history: %w

What it means

After successfully writing the boards row (insert or update), insertBoard writes an audit record into boards_history; if that INSERT Exec fails, this wrapped error is returned — the board itself may be persisted but the call reports failure. The board ID and driver error are logged server-side before wrapping.

Solutions

  1. Read the wrapped err and server log 'failed to insert board history' for the driver detail
  2. Run migrations to ensure the boards_history table exists and matches schema expectations
  3. Check DB health: disk space, connection stability, read/write permissions on boards_history
  4. Retry the operation — the main board row insert is the same operation, so a clean retry (with a new ID if duplicate-key arises) usually succeeds

Example fix

// before
// boards_history table missing after partial migration
// after: apply all migrations
migrate_db.sh  # creates boards_history
restart server
Defensive patterns

Strategy: retry

Try / catch

board, err := store.InsertBoard(board, userID)
if err != nil && strings.Contains(err.Error(), "failed to insert board") {
    // board may exist; check before retrying to avoid duplicate
    if existing, gerr := store.GetBoard(board.ID); gerr != nil || existing == nil {
        board, err = store.InsertBoard(board, userID)
    }
}

Prevention

When it happens

Trigger: Any successful board write followed by a failing boards_history insert — typically because the boards_history table is missing (incomplete migration), corrupted, or the DB connection dropped between the two statements.

Common situations: Upgrading from versions without history tables without running full migrations; manually pruning boards_history and dropping required constraints/columns; disk-full or read-only replicas; transient connection loss mid-transaction.

Related errors


AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30). Data as JSON: /api/errors/4e3b7e98283e02fd. Report an issue: GitHub.

Appendix: source

Thrown at server/services/store/sqlstore/board.go:398

			return nil, fmt.Errorf("insertBoard error occurred while updating existing board %s: %w", board.ID, err)
		}
	} else {
		board.CreatedBy = userID
		board.CreateAt = now
		insertQueryValues["created_by"] = board.CreatedBy
		insertQueryValues["create_at"] = board.CreateAt

		query := insertQuery.SetMap(insertQueryValues).Into(s.tablePrefix + "boards")
		if _, err := query.Exec(); err != nil {
			return nil, fmt.Errorf("insertBoard error occurred while inserting board %s: %w", board.ID, err)
		}
	}

	// writing board history
	query := insertQuery.SetMap(insertQueryValues).Into(s.tablePrefix + "boards_history")
	if _, err := query.Exec(); err != nil {
		s.logger.Error("failed to insert board history", mlog.String("board_id", board.ID), mlog.Err(err))
		return nil, fmt.Errorf("failed to insert board %s history: %w", board.ID, err)
	}

	return board, nil
}

func (s *SQLStore) patchBoard(db sq.BaseRunner, boardID string, boardPatch *model.BoardPatch, userID string) (*model.Board, error) {
	existingBoard, err := s.getBoard(db, boardID)
	if err != nil {
		return nil, err
	}

	board := boardPatch.Patch(existingBoard)
	return s.insertBoard(db, board, userID)
}

func (s *SQLStore) deleteBoard(db sq.BaseRunner, boardID, userID string) error {
	return s.deleteBoardAndChildren(db, boardID, userID, false)
}

View on GitHub (pinned to a84bbb65e3)