Solving The WordPress Error “An Automated WordPress update has failed to complete” Caused By Flywheel’s Core Modifications

Table of Contents

Flywheel, a managed WordPress hosting company, is known for its speed and reliability. However, we’ve observed a specific issue that has been causing trouble for many users – Flywheel modifies the core WordPress files. While this might not be a problem if you’re staying with Flywheel forever, the issue emerges when you move to another hosting provider.

In this post, we are going to shed light on a common error that arises due to Flywheel’s modifications and provide a solution to fix it.

 

The Flywheel Error

Users moving their WordPress site from Flywheel to another hosting provider often encounter a PHP fatal error that prevents certain plugins from updating. The error shows up for most users when an Automated WordPress update fails or when attempting to update a plugin from the WordPress Dashboard and seeing an unable to Update Plugin error message.

 

An Automatic WordPress Update has failed to complete
There has been a critical error on your website installing plugin from file.

Checking the PHP Error log will show an error message that looks something like this:

				
					error_log:[08-Nov-2022 07:12:08 UTC] PHP Fatal error: Uncaught Error: Call to undefined function fcp_copy_dir() in /home/mysite/public_html/wp-admin/includes/file.php:1896
				
			

The Culprit fcp_copy_dir

The problematic code lies within the WordPress core file file.php and looks like this:

				
					**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string   $from      Source directory.
 * @param string   $to        Destination directory.
 * @param string[] $skip_list An array of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir( $from, $to, $skip_list = array() ) {
        global $wp_filesystem;

        $files = fcp_copy_dir($from, $to, FS_CHMOD_FILE, FS_CHMOD_DIR, $skip_list);
        if ( false !== strpos( $files, 'FCP Operation Error' ) ) {
                return new WP_Error($files, $to);
        }
        $file_list = explode("\n", $files);
        foreach ($file_list as &$file) {
            wp_opcache_invalidate($file);
        }
        return true;

/*      $dirlist = $wp_filesystem->dirlist( $from );

        if ( false === $dirlist ) {
                return new WP_Error( 'dirlist_failed_copy_dir', __( 'Directory listing failed.' ), basename( $to ) );
        }

        $from = trailingslashit( $from );
        $to   = trailingslashit( $to );

        foreach ( (array) $dirlist as $filename => $fileinfo ) {
                if ( in_array( $filename, $skip_list, true ) ) {
                        continue;
                }

                if ( 'f' === $fileinfo['type'] ) {
                        if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
                                // If copy failed, chmod file to 0644 and try again.
                                $wp_filesystem->chmod( $to . $filename, FS_CHMOD_FILE );

                                if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
                                        return new WP_Error( 'copy_failed_copy_dir', __( 'Could not copy file.' ), $to . $filename );
                                }
                        }

                        wp_opcache_invalidate( $to . $filename );
                } elseif ( 'd' === $fileinfo['type'] ) {
                        if ( ! $wp_filesystem->is_dir( $to . $filename ) ) {
                                if ( ! $wp_filesystem->mkdir( $to . $filename, FS_CHMOD_DIR ) ) {
                                        return new WP_Error( 'mkdir_failed_copy_dir', __( 'Could not create directory.' ), $to . $filename );
                                }
                        }
                        // Generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list.
                        $sub_skip_list = array();

                        foreach ( $skip_list as $skip_item ) {
                                if ( 0 === strpos( $skip_item, $filename . '/' ) ) {
                                        $sub_skip_list[] = preg_replace( '!^' . preg_quote( $filename, '!' ) . '/!i', '', $skip_item );
                                }
                        }

                        $result = copy_dir( $from . $filename, $to . $filename, $sub_skip_list );

                        if ( is_wp_error( $result ) ) {
                                return $result;
                        }
                }
        }

        return true; */
}
				
			

The fcp_copy_dir() function is unique to Flywheel’s environment and is not a part of the standard WordPress core files. Therefore, when you migrate your website to a different hosting provider, the fcp_copy_dir() function becomes undefined, causing the fatal error when it is called upon.

The Solution

The resolution to this issue is quite simple – reinstall the WordPress core files. Unfortunately in some versions the broken code will prevent you from using WordPress to re-install core file. So the first step is to manually change the code in wp-admin/includes/file.php. Navigate to the function copy_dir( $from, $to, $skip_list = array() )

comment out or delete the FlyWheel custom code

				
					/** Commenting out FlyWheel Custom Code
$files = fcp_copy_dir($from, $to, FS_CHMOD_FILE, FS_CHMOD_DIR, $skip_list);
        if ( false !== strpos( $files, 'FCP Operation Error' ) ) {
                return new WP_Error($files, $to);
        }
        $file_list = explode("\n", $files);
        foreach ($file_list as &$file) {
            wp_opcache_invalidate($file);
        }
        return true;
*/
				
			

uncomment the original WordPress code so that the full function is as follows.

				
					**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string   $from      Source directory.
 * @param string   $to        Destination directory.
 * @param string[] $skip_list An array of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir( $from, $to, $skip_list = array() ) {
        global $wp_filesystem;

/** Commenting out FlyWheel Custom Code
$files = fcp_copy_dir($from, $to, FS_CHMOD_FILE, FS_CHMOD_DIR, $skip_list);
        if ( false !== strpos( $files, 'FCP Operation Error' ) ) {
                return new WP_Error($files, $to);
        }
        $file_list = explode("\n", $files);
        foreach ($file_list as &$file) {
            wp_opcache_invalidate($file);
        }
        return true;
*/

      $dirlist = $wp_filesystem->dirlist( $from );

        if ( false === $dirlist ) {
                return new WP_Error( 'dirlist_failed_copy_dir', __( 'Directory listing failed.' ), basename( $to ) );
        }

        $from = trailingslashit( $from );
        $to   = trailingslashit( $to );

        foreach ( (array) $dirlist as $filename => $fileinfo ) {
                if ( in_array( $filename, $skip_list, true ) ) {
                        continue;
                }

                if ( 'f' === $fileinfo['type'] ) {
                        if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
                                // If copy failed, chmod file to 0644 and try again.
                                $wp_filesystem->chmod( $to . $filename, FS_CHMOD_FILE );

                                if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
                                        return new WP_Error( 'copy_failed_copy_dir', __( 'Could not copy file.' ), $to . $filename );
                                }
                        }

                        wp_opcache_invalidate( $to . $filename );
                } elseif ( 'd' === $fileinfo['type'] ) {
                        if ( ! $wp_filesystem->is_dir( $to . $filename ) ) {
                                if ( ! $wp_filesystem->mkdir( $to . $filename, FS_CHMOD_DIR ) ) {
                                        return new WP_Error( 'mkdir_failed_copy_dir', __( 'Could not create directory.' ), $to . $filename );
                                }
                        }
                        // Generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list.
                        $sub_skip_list = array();

                        foreach ( $skip_list as $skip_item ) {
                                if ( 0 === strpos( $skip_item, $filename . '/' ) ) {
                                        $sub_skip_list[] = preg_replace( '!^' . preg_quote( $filename, '!' ) . '/!i', '', $skip_item );
                                }
                        }

                        $result = copy_dir( $from . $filename, $to . $filename, $sub_skip_list );

                        if ( is_wp_error( $result ) ) {
                                return $result;
                        }
                }
        }

        return true; 
}
				
			

Now you can reinstall the WordPress core files.

To reinstall WordPress core files:

  1. Log into your WordPress admin panel.
  2. Go to Dashboard > Updates.
  3. You’ll see a button saying ‘Re-install Now’ under the ‘Update WordPress’ option. Click on it.
  4. The system will download and replace the WordPress core files without affecting your content or customization.

Please note that this process should not affect your website’s data, but it’s always a good practice to back up your website before making any major changes.

Conclusion

While Flywheel’s modifications aim to provide a better hosting environment, they can cause issues when moving to a different hosting provider. By understanding the nature of these modifications and how to rectify the resulting errors, you can ensure a smoother transition for your WordPress website. Always remember to back up your site before making significant changes, and do not hesitate to seek professional help if you encounter any difficulties.

Is it time for a better WordPress host?

You might also like..

Are you wasting money on your current hosting provider?

Related Posts