How to Update WordPress Without Breaking It

by | Nov 12, 2020 | WordPress | 0 comments

Every time you update WordPress, things can go fine or they can go drastically wrong. Here are some tips to help you avoid problems whenever you update WordPress.

How to Manually Update WordPress

  1. Back up your site
  2. Create a staging site and turn off any caching plugins.
  3. Update one plugin on the staging site.
  4. Test the staging site for problems.
  5. If there are no problems, repeat steps 3-4 individually for the rest of the plugins. If there are problems, stop, troubleshoot, and fix if possible.
  6. Repeat steps 3-5 for the theme and again for the WordPress core software.
  7. Make notes of what went wrong from the above steps.
  8. Using your notes, make the same changes from step 3-5 to the live site, leaving out the plugin or theme update(s) that caused problems.
  9. Contact theme and plugin developers about the problems you encountered. For WordPress, check the support forums for known issues and log any new, genuine bugs by creating a ticket at
  10. Update WordPress core files last after updating plugins and themes (in that order).

Don’t Worry If You Forgot to Update WordPress

When was the last time you updated your WordPress plugins and themes? Or WordPress itself? If the answer is “a long time ago”, there’s no need to panic. You can easily update WordPress and without breaking things.

Updating the plugins is a good idea, of course. Doing so ensures that you have the latest code for purposes of improving security, performance, and getting rid of bugs found in prior versions.

However, WordPress updates are something that a lot of website owners find to be uncomfortable at the very least and terrifying at the worst. And with good reason! If you update WordPress plugins, themes, and/or core files, and it breaks your site, you have to scramble to restore the prior version of the stuff you updated. Or, even worse, you have to restore your entire site from a backup!

You don’t have to feel anxiety over this necessary task. Just take a deep breath, get methodical, and dive in with the information presented below.

Why Not Simply Use WordPress Automatic Background Updates?

Automattic introduced a new automatic background updating feature in version 3.7 of WordPress. It was meant to streamline and simplify the normally menial (and forgettable) chore of updating core, theme, and plugin files.

While that is helpful to a lot of users, it comes with an Achilles Heel problem. The weakness is that when you let the updates happen on their own, a human is usually not present to ensure that the update didn’t break something. For sites that earn revenue through ads or eCommerce, this can be a very bad thing. Especially if the site is down for hours or days before the problem is discovered.

Fortunately, there is a way to disable all updates, or just configure core updates, using the wp-config.php file or filters.

Best Practices for Updating WordPress Websites

The best practice, then, is to have a staging site. A staging site is an exact copy of your live site that sits on a different URL, such as “” or “” or “”. Most web hosts will provide a pricing plan that includes some sort of staging site capability.

For example, our preferred hosting service,, gives you not only a test environment but a development environment as well as multiple “mini-dev” environments for your team members to work on individually. This is an important feature at Pantheon because of how tightly Pantheon controls its WordPress, app server, web server, and operating system configurations for security and performance. Pantheon gives you the opportunity to test vigorously before going live. This is important because what works on a vast majority of WordPress hosts who haphazardly ignore security and performance for the convenience of their users may not work the same way on Pantheon. Pantheon has a “righteously opinionated” prioritization of security and performance over convenience.

Once you have a staging site set up, you can then update WordPress. Do the core, theme, or plugin update on the staging site to see how things will behave, or if the site will break.

Do each update one at a time. For example, first, do the plugins one by one. Test the site after each plugin is updated, paying the most attention to the functionality that the plugin provides. Do that until each plugin is done. Then do the theme. Test the site. And then follow with the core WordPress update. Test the site again.

The reason you want to update WordPress piece by piece is so that you don’t have to guess which of multiple simultaneously updated pieces broke the site if a problem occurs. Going one-by-one shows you that it was the change you just made that is most likely the culprit.

If the site doesn’t have any problems after the updates, you’re golden! Go ahead and update WordPress on the live site.

How Do I Update WordPress Core?

First of all, you’ll want to update WordPress core software after you’ve successfully applied and individually tested the plugin and theme updates. This is due to plugin and theme authors tending to release updated code to stay ahead of WordPress core updates. If you do it the other way around, your plugins and theme may break.

How you update WordPress core files depends on your hosting. Most hosting companies have an installer app to update WordPress in their hosting dashboards that either let you auto-update core or gives you a button to do it. Or, you can simply run the update within your WordPress Dashboard.

Other hosts (the better ones, in my humble opinion), will apply a disciplined software versioning approach to all updates, including WordPress core. In other words, they’ll use a version control system (VCS) such as Git or SVN. Among other things, these VCS systems ensure that, if you need to you can roll back to a prior version of the software if something goes wrong. In those cases, you’ll want to use the VCS workflow the host provides rather than directly update WordPress in the Dashboard or in some kind of installer app. is an example of one host that uses Git to control the deployment of core updates.

What to Do If An Update Breaks Your WordPress Site

If, however, the site does have problems, you’ll want to troubleshoot the issues before updating the live site.

Turn off all plugins and change to the default WordPress theme (it’s named after the most current year, such as “Twenty Twenty”). Now check to see if the problem is still occurring. Turn on plugins or themes one-by-one and test the problem again to see if it appears. If it does, you know that plugin or theme is likely to have caused the problem.

Make a note of the plugins or theme that caused the site problems and make sure that when updating the live site that you don’t update those components.

Also, don’t add more plugins to the mix as you test and troubleshoot. If you do have to add more plugins as part of testing and troubleshooting, make sure that you remove them again.

Sometimes you have to wait for another release of the plugin for the problem to be resolved. And, it doesn’t hurt to contact the plugin developer and let them know there’s a problem. You can try using the WordPress support forums to ask others for help, and even submit new bugs to the WordPress development team at

Why Does WordPress Break After Updates?

There’s a lot that can go wrong when you update WordPress after a long time of letting it go without patches. Below is an example of an update that happened to the WooCommerce plugin for eCommerce.

But first, to understand the magnitude and potential impact of software releases, you have to understand the numbering system.

Typically it consists of three numbers separated by decimals. They are: the major release number, the minor release number, and the point release number.

For the WooCommerce update we’re discussing, it was a significant release in that the minor release (second digit) and point release (third digit) in the release number increased by 1 and decreased to 0, respectively from 3.5.9 to 3.6.0. This was a quick indicator that pointed to a rather extensive list of changes (shown in the changelog below).

3.6.1 – 2019-04-18
Fix – Remove calls to ‘header_register_callback’ to prevent conflicts with some hosting providers and PHP versions.
3.6.0 – 2019-04-17
Enhancement – Merged WooCommerce Gutenberg Products Block feature plugin. Adds blocks for the new editor, including
hand picked products, featured products, products by category/attribute, sale products, new products, top rated
products, and best selling products. #22954
Enhancement – Only include order erasure bulk action if erasure is enabled in settings. #22354
Enhancement – Customer notes containing URLs now automatically converts to clickable links. #21927
Enhancement – Add increase and decrease stock options to bulk edit form. #22475
Enhancement – Allow states in zones to be searched by country name. #22339
Enhancement – Added registration success notices to account pages. #22650
Enhancement – Store notice is visible again if the notice text is changed. #22645
Enhancement – Add aria-label attribute to shop orderby selector to improve accessibility. #22683
Enhancement – When adding, editing, and deleting items manually from orders, the corresponding product stock will be
updated to reflect the event and an order note will log the event. #22329
Enhancement – Added suggestions for official extensions to Products, Edit Product and Orders screens.
Enhancement – Store attribute values as post_excerpt for variations to support easier searching for variations. #22083
Enhancement – Improved username generation and introduced wc_create_new_customer_username function. #23145
Enhancement – Allow opting out of Marketplace Suggestions 23218
Tweak – Generalize shipping estimate text on cart page. #22467
Tweak – Include auto draft orders in order list filters. #22380
Tweak – Only include the network orders widget on the main site dashboard. #22318
Tweak – Only show available shipping continents when selecting shipping zone region. #22131
Tweak – Use Shortcode block on default WooCommerce pages. #21817
Tweak – Show full category hierarchy in product URLs when term IDs are not sequential. #22526
Tweak – Make sure account and checkout endpoints only work under account and checkout pages. #22631
Tweak – Show loading graphic when order form is submitted. #22664
Tweak – Add alt text to gallery images #22863
Tweak – Improved display_name generation during checkout. #22786
Tweak – Send correct calling code and phone number to PayPal standard when using non-US addresses. #22693
Tweak – Added tooltip to refund-amount input box and made it readonly when taxes are enabled. #22820
Tweak – Remove admin alert for the WooCommerce Gutenberg Products Block feature plugin. #22982
Tweak – Setup Wizard: support keyboard navigation to toggle on/off features. #22936
Tweak – Set reply-to address for all emails. #22979
Tweak – Setup wizard redirection improvements. #22977
Tweak – Simplify display of discount amounts within orders. #22949
Tewak – Remove Marketplace Suggestions from product listing page. #23211
Template – Moved the order of rememberme checkboxes for accessibility so they tab in order. #21454
Template – New structure for attributes template, including new woocommerce_display_product_attributes filter. #22480
Template – Admin cancelled order email reworded. #22971
Dev – Update action scheduler to version 2.2.2. #23162
Dev – Update action scheduler to version 2.2.1. #23016
Dev – Use ActionScheduler for database updates. Improved update notice. #22904
Dev – Introduce woocommerce_reviews_title filter. #22216
Dev – Added woocommerce_cheque_process_payment_order_status filter allowing plugins to change the order status to the Cheque gateway. #21402
Dev – Add the current coupon object to the woocommerce_get_shop_coupon_data filter. #21442
Dev – New filter woocommerce_gallery_image_html_attachment_image_params for manipulating gallery images. #22005
Dev – New filter woocommerce_widget_get_current_page_url for manipulating links in widgets. #21537
Dev – Move wc_get_template filter to allow plugins to register locations for template files that do not exist in WooCommerce core. #21764
Dev – Add support for custom classes on global/quantity-input.php. #21553
Dev – Pass product object to woocommerce_add_to_cart_redirect filter where appropriate. #22123
Dev – Add support for forgetting the cart contents and user session when switching between accounts using the User Switching plugin. #21991
Dev – Added a consistent form class to the Track Order Form. #21991
Dev – Add $orderby and $order params to filter woocommerce_get_catalog_ordering_args. #22257
Dev – Add new pre query filter to WC_Product_Data_Store_CPT::search_products(). #22165
Dev – Added additional parameters to the woocommerce_variation_option_name filter. #21153
Dev – Added new filter woocommerce_get_min_max_price_meta_query. #22255
Dev – Added a filter to WC_REST_CRUD_Controller::get_collection_params method to allow developers to change params in
the same way as WP_Rest_Posts_controller::get_collection_params. #21562
Dev – Add $zone param to woocommerce_shipping_zone_before_methods_table and woocommerce_shipping_zone_after_methods_table actions. #21961
Dev – Added woocommerce_geolocation_ajax_get_location_hash filter. #22350
Dev – Added woocommerce_variation_prices_array filter. #21003
Dev – Added wc_emptied_cart javascript event when cart is emptied. #22469
Dev – Switched woocommerce_ordered_again hook to ref_array. #22425
Dev – woocommerce_checkout_before_order_review_heading action added in checkout form template. #22481
Dev – Added woocommerce_variation_header hook in variations list. #21341
Dev – Add a filter, woocommerce_current_user_can_edit_customer_meta_fields, to bypass manage_woocommerce when editing customer meta fields. #22277
Dev – Adds filter on the return value of function ‘get_item_tax_rates’. This gives developers the possibility to
prevent the mandatory caching of tax rates. #22488
Dev – Add filters for mail callback in WC_Email::send method. #22394
Dev – Add an instance method to WC_Admin_Taxonomies. #21884
Dev – Added woocommerce_order_is_pending_statuses filter and wc_get_is_pending_statuses function. #22409
Dev – Filter save_payment_method_checkbox to allow “Save to account” checkbox to be removed from the checkout form. #21859
Dev – Added triggers to the gallery script to allow 3rd parties to run scripts before and after initialization. #22501
Dev – Added woocommerce_add_to_cart_qty_html filter. #21069
Dev – Prevent extract from polluting hook arguments in wc_get_template(). #21722
Dev – Add woocommerce_pre_remove_cart_item_from_session hook to allow removal of cart items when the cart is loaded from the session. #22290
Dev – Add $attribute to woocommerce_product_option_terms filter. #21648
Dev – Added error handling and timeout to cart fragment ajax call. #21043
Dev – Remove unused legacy ‘woocommerce_lock_down_admin’ option and use filter only instead. #17796
Dev – Allow custom settings sections in the Shipping tab. #21719
Dev – Update Emogrifier library to 2.1. #22342
Dev – Moved core state codes to a single file. #22339
Dev – Adds filter for product categories displayed by product_categories shortcode. #22571
Dev – Moves cart hash calculation to WC_Cart class. #21050
Dev – Removed deprecated Simplify gateway. #22410
Dev – Added woocommerce_paypal_force_one_line_item filter to control how items are sent to PayPal. #22653
Dev – Added woocommerce_update_product_stock_query to filter the direct sql query to update product stock. #22672
Dev – Added woocommerce_product_loop_title_classes filter to modify product title loop classes. #22717
Dev – Delay woocommerce_loaded hook until all plugins are loaded. #22536
Dev – Added woocommerce_product_price_class filter to modify product price classes. #22748
Dev – woocommerce_product_stock_status_options filter added for stock status options. #22834
Dev – woocommerce_before_cart_emptied action before cart is emptied. #22846
Dev – Added filters for shipping options – woocommerce_shipping_ID_option and woocommerce_shipping_ID_instance_option. #22771
Dev – Refactor comment/rating update functions. #22909
Dev – Introduced wc_sanitize_phone_number() function. #22962
Dev – Added woocommerce_get_product_subcategories_cache_key filter to allow the cache to be renamed if for instance
the site runs in multiple languages and needs a unique cache per language. #22915
Dev – Inactive, MU, Dropin plugins and account connection status added to System Status Report. #22887
Dev – Make error handling consistent in payment processing for pay page and checkout. #22916
Dev – Improved usage and event tracking (if opted in). #22955
Dev – Pass class context to woocommerce_email_styles filter. #23027
Fix – Use correct address for taxes when applying/removing coupons. #22802
Fix – Hide ratings on the shop page when reviews are disabled. #22476
Fix – Fix W3C validation of single product page quantity input. #22333
Fix – Give product variations a unique guid after creation. #22324
Fix – Deduct correct refunded amounts in calculated net daily sales export CSV. #22518
Fix – Country sorting for stores which use a language that uses a lot of accented characters, e.g. Spanish. #22417
Fix – Customer VAT exempt status now carries through to order when placed via checkout. #22458
Fix – Handle full refunds for taxes by code report. #21843
Fix – Option “Used for variations” should show only for variable products when saving attributes. #22524
Fix – Allow pa_ in product attribute slugs. #22112
Fix – Fix customer creation dates in API. #22269
Fix – Get widget instance setting defaults so it shows in customiser before save. #22345
Fix – PR state codes. #22339
Fix – Allow selecting states from the Country / State drop-down for your store address when you have the option
enabled to sell to specific countries. #22339
Fix – Restrict the price filter widget to filtering the main product query. #22621
Fix – Default placeholder image resizing. #22443
Fix – HTML tags should be stripped from description in Structured Data of Product. #22596
Fix – For logged in customers, pull default address fields from customer object, not session object, to avoid incorrect mixes of data. #22392
Fix – Misc tax rounding improvements. #22420
Fix – Respect shop page subcategories setting when page/N/ is added to the URL. #22589
Fix – Check for decoded taxonomy name when unsetting product terms. #22740
Fix – If date paid is not set but payment complete status has passed, set it. #22735
Fix – Prevent webhooks for drafts, and correct create vs updated for manual orders. #22731
Fix – Ignore invalid default customer locations. #22357
Fix – The state select field was missing a placeholder. #22357
Fix – Fix state field rendering when customer address is not in a valid selling country. #22357
Fix – Correctly handle negative fees when using the REST API. #22782
Fix – Make sure local_pickup taxes do not hang around when local_pickup is not available for the selected location during checkout. #22826
Fix – Remove Plugin and Theme background installer hooks, cannot run as there are no events scheduled for it. #22799
Fix – Trigger zoom if moving cursor over image quickly in product gallery. #22784
Fix – PayPal: Add meta data, before changing order status. #22892
Fix – Make price filter widget tax aware when you have excl prices entered but show prices incl of tax. #22540
Fix – Loop attribute panels to disable options rather than look at values to prevent notices. #22891
Fix – When deleting zone methods, also remove setting options. #22867
Fix – Correctly show state fields after posting the edit address form. #22948
Fix – Validate coupon usage limit for manual orders correctly before order is saved. #22980
Fix – Make coupon code sanitization match post_title sanitization. #22945
Fix – Ensure WC_Helper sees plugin activation events via CLI. #22972
Fix – Setup wizard redirection improvements. #22977
Fix – Correctly show stock status for products when manually creating an order in the admin. #22997
Fix – After logging in update customer session ID. #23001
Fix – Narrow viewport css in setup wizard. #23033
Fix – Allow entering of date only ( no time ) when placing a singular product on sale. #22973
Fix – Download link URL in helper. #23146
Fix – Completed email wording update. #23128
Fix – REST API: Allow filtering by future status #23138
Fix – Update refund reason to make it clear process is manual. #23149
Fix – Hide stock status for variations when the parent is managing stock. #23069
Fix – Force variation product type in WC_Ajax::add_variation. #23131
Fix – WooCommerce writes current_theme_supports_woocommerce option on every regular page view. #23035
Fix – Update the rating request text in the footer to be friendlier for screen reader users. #23039
Fix – Null check variable before accessing its properties on checkout page. #23047
Fix – Recognize all input fields with ID for checkout fields. #23050
Fix – Avoid regenerating thumbnails on every page load. #21800
Fix – Changed ‘private’ methods on WC_Breadcrumb class to ‘protected’. #23057
Fix – Jumping to top of page when dismissing store notice. #23066
Fix – Backwards compatibility issues with wc_get_template #23197
Fix – Remove date restriction of Facebook Plugin feature in OBW #23210
Fix – Updates to usage tracking logic #23231
Fix – Add get_post_status helper method and ensure prefix gets added for most statuses #23203
Fix – Add link to suggstions management #23229
Fix – Make usage tracking opt-out text more clear #23216
Fix – CSS Issues with suggestions display #23241
Fix – Product search may fail to return valid results when using the ‘include’ flag to search within a limited set.
Fix – Change aria-labelledby to aria-label on quantity input. #23186
Performance – Product meta data lookup table used for sorting and slow queries. #22718
Performance – Prime caches when reading variations. #22587
Performance – Only include REST API classes and objects during rest_api_init hook. #22615
Performance – Improved how versioned transients are set/cleanup to avoid cron. #22511
Performance – Optimized product CSS class functions to avoid multiple product reads and duplication. #22610
Performance – Improved caching of template loader, product types, and layered nav widget. #22612
Performance – Remove external lookup of IP addresses on localhost. #22608
Performance – Improved speed of the find_matching_product_variation variation lookup function. #22423
Performance – Prevent frontend code from being loaded during REST API. #21090
Performance – Load only active webhooks on pages and allow limits to be set by developers. #22760
Performance – Index on downloadable_product_permissions to improve speed when fetching downloads for customers. #22906
Performance – Improved term ordering queries, making the sorting apply by default via the DB query rather than sorting
all terms with PHP. Removed legacy term meta table usage. #22570
Performance – Use day, not time, in status widget for caching. #22950
Performance – Improve slow term ordering by using queries instead of php. #22570
Performance – Removes legacy woocomerce_termmeta table and swap out all calls to legacy term meta functions to the new WP ones. #22570
Performance – Apply term sorting using get_terms_defaults hook instead of custom parameters. #22570
Performance – Use pre_get_terms hook to detect menu_order sorting param and apply to the term query. Meta sorting is now possible through WP. #22570
Performance – Use terms_clauses hook to support numeric name sorting and to improve the menu order sorting so it works if meta is missing. #22570
Performance – Added caching to System Status Report. #22887
Performance – Delete empty meta on update in data-stores. #22773
Performance – Image regeneration edge cases. #22818
Performance – Don’t query for an order count unnecessarily. #22984
Performance – Add caching to attribute functions. #22938
Performance – Add ability to run product lookup table updates via WP CLI. #23031
Localization – Modify administrative regions of Greece to default to their english ISO 3166-2 names, instead of using the native GR names. #21945
Localization – Added US Minor Outlying Islands as states to avoid confusion with US. #22468
Localization – Dutch postcode validation. #22316
Localization – Made municipality address field optional for Latvia. #22487
Localization – Added new Venezuelan currency Bs S. #22435
Localization – Added Danish locale. #22495
Localization – Update Peruvian currency. #22602
Localization – Update CA address format. #22692
Localization – Updated JP field order. #22774

As you can see, many enhancements and tweaks occurred in the upgrade to WooCommerce 3.6.0.

Big releases like these are risky updates to make for a variety of reasons. The main problem is that it is difficult, if not impossible, to fully test each feature to ensure it will work on all websites. Developers will test their code on a variety of different systems and configurations, but the variability of potential conflicts with any number, combinations, and versions of plugins and themes written by third parties is impossible to fully know, let alone test universally. Such is the nature of free and open-source software (FOSS).

Therefore, when major releases drop, it is incumbent on each site owner to test their own site for problems when they update WordPress.

With the WooCommerce 3.6.0 release, many people (most of whom were panicked because they updated directly to their live sites and didn’t test first) complained that products wouldn’t display right, categories didn’t work correctly, and checkout flows broke.

The next release was a “point release” from 3.6.0 to 3.6.1. It consisted of a single fix, which was to remove a function call that caused conflicts with certain hosting providers and versions of PHP (the application server on which WordPress runs). The 3.6.1 release benefited many users but didn’t help all of them. Their particular situational fixes will come in future releases, or not at all, depending on what the root cause of the problem was for their particular install.


Be sure to test on a staging environment before going live when you update WordPress. Test after every plugin, theme or WordPress core change to ensure that the site is working properly. It is always a good idea to use a code versioning system to keep track of code changes and be able to roll back to older code.

Related Article

5 Best Tips to Improve WooCommerce Security

The following two tabs change content below.
Rob Watson is an online business coach and marketing consultant. Beginning in 1996 as a self-taught web designer, he has created websites for everyone from small business owners to multi-national companies. Rob now provides one-to-one coaching for digital business website owners. He is the co-organizer of the West Orlando WordPress Meetup and a WordCamp speaker.


Submit a Comment

Your email address will not be published.

Pin It on Pinterest

Share This