Make WordPress Core

Opened 3 years ago

Closed 5 months ago

#57469 closed defect (bug) (fixed)

retrieve_widgets(): fatal error when a sidebar's widgets set to null (array is expected)

Reported by: kesselb's profile kesselb Owned by: westonruter's profile westonruter
Milestone: 6.9 Priority: normal
Severity: normal Version: 4.9
Component: Widgets Keywords: has-patch has-unit-tests commit
Focuses: Cc:

Description (last modified by hellofromTonya)

When changing from PHP 7.4 to PHP 8.0 it's not possible to activate our theme.

Fatal error: Uncaught Error: array_merge(): Argument #3 must be of type array, null given in wp-includes/widgets.php on line 1342
array_merge()
wp-includes/widgets.php:1342

retrieve_widgets()
wp-includes/widgets.php:1287

_wp_sidebars_changed()
wp-includes/class-wp-hook.php:310

WP_Hook::apply_filters()
wp-includes/class-wp-hook.php:332

WP_Hook::do_action()
wp-includes/plugin.php:517

do_action()
wp-includes/theme.php:3395

check_theme_switched()
wp-includes/class-wp-hook.php:308

WP_Hook::apply_filters()
wp-includes/class-wp-hook.php:332

WP_Hook::do_action()
wp-includes/plugin.php:517

do_action()
wp-settings.php:617

require_once()
wp-config.php:103

require_once()
wp-load.php:50

require_once()
wp-admin/admin.php:34

require_once()
wp-admin/plugins.php:10

Line 1342:

<?php

$shown_widgets = array_merge( ...array_values( $sidebars_widgets ) );

$sidebars_widgets

array (
  'wp_inactive_widgets' => 
  array (
  ),
  'sidebar-standard' => 
  array (
  ),
  'sidebar-marken' => NULL,
  'sidebar-typen' => NULL,
  'sidebar-test' => NULL,
  'sidebar-zubehoer' => NULL,
  'sidebar-ratgeber' => NULL,
)

PHP 8.0+ throws a type error when a non-array value is given to array_merge.

I guess NULL is not a valid value for the sidebar widgets.
Maybe our theme wrote this weird state to the options field.

Patch: https://github.com/WordPress/wordpress-develop/pull/3848

Attachments (4)

Screenshot from 2023-01-15 21-45-32.png (173.2 KB) - added by kesselb 3 years ago.
Screenshot from 2023-01-15 21-46-30.png (77.4 KB) - added by kesselb 3 years ago.
sidebar-null-values-before.mp4 (1.3 MB) - added by lakshyajeet 6 months ago.
Before the fix
sidebar-null-values-after.mp4 (1.5 MB) - added by lakshyajeet 6 months ago.
After the fix

Change History (31)

This ticket was mentioned in PR #3848 on WordPress/wordpress-develop by kesselb.


3 years ago
#1

  • Keywords has-patch has-unit-tests added

wp_map_sidebar_widgets is called in retrieve_widgets and is expected to return array<string, array>.

Before this change it was possible to return something like ['sidebar-1' => [], 'sidebar-2' => null].

array_merge in PHP 8.0 is stricter and throws an TypeError when null given.

PHP 7.4: array_merge(...[['hello', 'world'], null]) => null
PHP 8.0: array_merge(...[['hello', 'world'], null]) => Fatal error

Trac ticket: https://core.trac.wordpress.org/ticket/57469

#2 @audrasjb
3 years ago

  • Keywords php8 added
  • Milestone changed from Awaiting Review to 6.2
  • Version 6.1.1 deleted

Thanks for the ticket, the patch and the unit tests!

I left a comment in the PR.
Moving for 6.2 consideration.

#3 follow-up: @jrf
3 years ago

  • Keywords close added
  • Milestone 6.2 deleted

@kesselb Thanks for the ticket.

To be honest, this sounds like user error and something which should be fixed in the theme, not in WP Core.

If anything, a _doing_it_wrong should be thrown when receiving invalid data (as is the case with your use-case).

#4 @kesselb
3 years ago

Hi,

If anything, a _doing_it_wrong should be thrown when receiving invalid data (as is the case with your use-case).

Sounds good ;)

<?php
function check_sidebars_widgets_for_invalid_values($value)
{
        if (is_array($value)) {
                $value = array_filter($value, static function ($var) {
                        return $var !== null;
                });
        }
        return $value;
}

/**
 * Upgrade to PHP 8 fails on some pages with an uncaught error:
 *
 * array_merge(): Argument #3 must be of type array, null given in wp-includes/widgets.php on line 1342
 *
 * Starting with PHP 8 array_merge is stricter about null values.
 * This filter will remove sidebars with null as value.
 */
add_filter('option_sidebars_widgets', 'check_sidebars_widgets_for_invalid_values', 1, 1);

If anyone has a similar issue. The above filter prevent the fatal error.

#5 @hellofromTonya
3 years ago

  • Description modified (diff)
  • Keywords php80 added; php8 has-patch has-unit-tests removed
  • Summary changed from Uncaught Error: array_merge(): Argument #3 must be of type array, null given in wp-includes/widgets.php on line 1342 to retrieve_widgets(): fatal error when a sidebar's widgets set to null (array is expected)
  • Version set to 4.9

Changes in the ticket:

  • Updated the Summary to better reflect the issue being reported, i.e. for discoverability.
  • Updated the Version to 4.9.
  • Wrapped the PHP error in the Description.
  • Reset the keywords as the PR was closed.
  • Changed keyword to php80 to identify which PHP version increased the error's severity.

Error across PHP versions:
If null or a non-array is set for the widgets of a sidebar, then PHP throws an error (see it in action https://3v4l.org/i45nZ):

  • < 7.3: Warning: array_merge(): Argument #3 is not an array
  • PHP 7.3 to 7.4: Warning: array_merge(): Expected parameter 3 to be an array, null given
  • PHP 8+: Fatal error: Uncaught TypeError: array_merge(): Argument #3 must be of type array, null given.

Historical context:

  • [41555] / #39693 (during WP 4.9):
    • Introduced wp_map_sidebars_widgets().
    • retrieve_widgets():
      • Invoked wp_map_sidebars_widgets() to map $sidebars_widgets
      • Added $shown_widgets = call_user_func_array( 'array_merge', $sidebars_widgets );.
  • [48839] / #50913 (during WP 5.6):
    • retrieve_widgets(): changed call_user_func_array( 'array_merge', $sidebars_widgets ); to array_merge( ...array_values( $sidebars_widgets ) );.

#6 in reply to: ↑ 3 @hellofromTonya
3 years ago

  • Resolution set to invalid
  • Status changed from new to closed

Replying to jrf:

To be honest, this sounds like user error and something which should be fixed in the theme, not in WP Core.

I agree. The error flagging null as the wrong data type and informing it should an array has been present for a long time. This is a case of doing it wrong.

I'm all for defensive code to protect Core's source code. However, sometimes a native PHP error is appropriate.

When changing from PHP 7.4 to PHP 8.0 it's not possible to activate our theme.

I think in this case, not being able to activate a theme is not severe enough to warrant adding defensive guard and _doing_it_wrong().

A user using the theme with the issue upgrading to PHP 8+ would experience a fatal error, which would require manual action to restore the site. Changing Core's code for this scenario is dependent upon the frequency of this scenario happening. But I'm not seeing other reports to null for widgets causing a fatal error.

Thus, I tend to agree with @jrf to close this ticket as something to be fixed in the theme.

#7 @hellofromTonya
3 years ago

#58351 was marked as a duplicate.

#8 @hellofromTonya
3 years ago

#58351 reported the same issue but happened after switching themes:

In some subsites, that after switched themes I get the following PHP Fatal error.

@lenasterg As noted in this ticket, the root cause seems to be a problem in the theme. Can you confirm if switching back to the original theme or to a different theme resolved the issue?

#9 @janthiel
2 years ago

Hey there, just came across this issue on a recent WordPress 6.4.2 installation switching a working site with the "Enfold" Theme to "Twenty Twenty-Four" Theme.

Uncaught exception (TypeError): “array_merge(): Argument #3 must be of type array, null given“ at `./wp-includes/widgets.php:1346`.

If this is a "User Error" I am not aware of any obvious one. The site was working perfectly fine before.
We switched back to Enfold using WP-CLI but the site remains broken with the same error.

#10 @janthiel
2 years ago

Deleting the "theme_mods_twentytwentyfour" option from the DB made the site useable again.

This was the content of that option:

a:3:{i:0;b:0;s:18:"nav_menu_locations";a:0:{}s:19:"wp_classic_sidebars";a:6:{s:13:"av_everywhere";a:11:{s:4:"name";s:20:"Displayed Everywhere";s:2:"id";s:13:"av_everywhere";s:11:"description";s:0:"";s:5:"class";s:0:"";s:13:"before_widget";s:48:"<section id="%1$s" class="widget clearfix %2$s">";s:12:"after_widget";s:59:"<span class="seperator extralight-border"></span></section>";s:12:"before_title";s:24:"<h3 class="widgettitle">";s:11:"after_title";s:5:"</h3>";s:14:"before_sidebar";s:0:"";s:13:"after_sidebar";s:0:"";s:12:"show_in_rest";b:0;}s:7:"av_blog";a:11:{s:4:"name";s:12:"Sidebar Blog";s:2:"id";s:7:"av_blog";s:11:"description";s:0:"";s:5:"class";s:0:"";s:13:"before_widget";s:48:"<section id="%1$s" class="widget clearfix %2$s">";s:12:"after_widget";s:59:"<span class="seperator extralight-border"></span></section>";s:12:"before_title";s:24:"<h3 class="widgettitle">";s:11:"after_title";s:5:"</h3>";s:14:"before_sidebar";s:0:"";s:13:"after_sidebar";s:0:"";s:12:"show_in_rest";b:0;}s:8:"av_pages";a:11:{s:4:"name";s:13:"Sidebar Pages";s:2:"id";s:8:"av_pages";s:11:"description";s:0:"";s:5:"class";s:0:"";s:13:"before_widget";s:48:"<section id="%1$s" class="widget clearfix %2$s">";s:12:"after_widget";s:59:"<span class="seperator extralight-border"></span></section>";s:12:"before_title";s:24:"<h3 class="widgettitle">";s:11:"after_title";s:5:"</h3>";s:14:"before_sidebar";s:0:"";s:13:"after_sidebar";s:0:"";s:12:"show_in_rest";b:0;}s:11:"av_footer_1";a:11:{s:4:"name";s:17:"Footer - Column 1";s:2:"id";s:11:"av_footer_1";s:11:"description";s:0:"";s:5:"class";s:0:"";s:13:"before_widget";s:48:"<section id="%1$s" class="widget clearfix %2$s">";s:12:"after_widget";s:59:"<span class="seperator extralight-border"></span></section>";s:12:"before_title";s:24:"<h3 class="widgettitle">";s:11:"after_title";s:5:"</h3>";s:14:"before_sidebar";s:0:"";s:13:"after_sidebar";s:0:"";s:12:"show_in_rest";b:0;}s:11:"av_footer_2";a:11:{s:4:"name";s:17:"Footer - Column 2";s:2:"id";s:11:"av_footer_2";s:11:"description";s:0:"";s:5:"class";s:0:"";s:13:"before_widget";s:48:"<section id="%1$s" class="widget clearfix %2$s">";s:12:"after_widget";s:59:"<span class="seperator extralight-border"></span></section>";s:12:"before_title";s:24:"<h3 class="widgettitle">";s:11:"after_title";s:5:"</h3>";s:14:"before_sidebar";s:0:"";s:13:"after_sidebar";s:0:"";s:12:"show_in_rest";b:0;}s:11:"av_footer_3";a:11:{s:4:"name";s:17:"Footer - Column 3";s:2:"id";s:11:"av_footer_3";s:11:"description";s:0:"";s:5:"class";s:0:"";s:13:"before_widget";s:48:"<section id="%1$s" class="widget clearfix %2$s">";s:12:"after_widget";s:59:"<span class="seperator extralight-border"></span></section>";s:12:"before_title";s:24:"<h3 class="widgettitle">";s:11:"after_title";s:5:"</h3>";s:14:"before_sidebar";s:0:"";s:13:"after_sidebar";s:0:"";s:12:"show_in_rest";b:0;}}}

#11 @ikriv
2 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

I was sitting on an old theme for a few years, and I hit this bug. I would see a TypeError exception in array_merge() any time I open the 'widgets' page, or after I have upgraded to a new theme.

This seems to be caused by corrupted widgets information in the database. An investigation showed that $sidebars_widgets array contains a NULL item with key 'subsidiary'.
I.e. it looked like this:

(
    [wp_inactive_widgets] => Array(...)
    [primary] => Array(...)
    [subsidiary] => NULL
)

Since $sitebars_widgets is a global variable, it is hard to tell who and why was adding a NULL element. Anyway, the problem goes away if I add the following to retrieve_widgets() in wp-incudes/widgets.php just before the call to _wp_remove_unregistered_widgets():

	// remove any NULL elements
	$sidebars_widgets = array_filter($sidebars_widgets);

I suggest to reopen this bug and add this filter to the production version: corrupted databases happen, and it's an easy precaution.

Last edited 2 years ago by ikriv (previous) (diff)

#12 @bartnv
2 years ago

Just a quick confirmation: I had this problem too and couldn't find the source. The line of code @ikriv suggests above worked to solve it for me.

#13 @janthiel
20 months ago

  • Keywords has-patch has-unit-tests added; php80 close removed

@hellofromTonya just wanted to re-ping you about this issue. It seems obvious that this is not related to a specific Theme doing something wrong as detailed within this ticket. The broken data might just be inserted by any Theme or Plugin without the knowledge of the user.

Then when switching from <any> Theme to twenty24 for example the site is broken. Causing frustration as the "old" theme obviously worked before.

There are two fixes. One as a patch and the other one in: https://core.trac.wordpress.org/ticket/57469#comment:11

We tested the second one and as simple as it is, it simply works ;-)
Should be a safe ticket for 6.6 as it has no real negative impact at all. Shouldn't it?

What do you mean?

Thank you!

#14 @mtg169
12 months ago

We get various user reports of this. What I've found is that the sidebar_widgets option in the database is not a null value, but processing on the value during a theme change ends up looking at a null value. On all of the sites I've seen this happen on when changing themes, the value primarily only has inactive widgets. Setting the sidebars_widgets option to an empty serialized array a:0:{} in the database is another workaround.

If reproducible data is needed, this is an option I saved from a previous site:

INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('sidebars_widgets','a:6:{s:19:\"wp_inactive_widgets\";a:5:{i:0;s:6:\"text-2\";i:1;s:6:\"text-3\";i:2;s:6:\"text-4\";i:3;s:25:\"google_translate_widget-3\";i:4;s:13:\"custom_html-3\";}s:9:\"sidebar-1\";N;s:9:\"sidebar-2\";a:2:{i:0;s:18:\"facebook-likebox-3\";i:1;s:13:\"media_video-3\";}s:9:\"sidebar-3\";a:2:{i:0;s:12:\"blog-stats-3\";i:1;s:11:\"tag_cloud-3\";}s:9:\"sidebar-4\";a:2:{i:0;s:11:\"top-posts-3\";i:1;s:14:\"recent-posts-3\";}s:13:\"array_version\";i:3;}','yes');

Deleting any existing option and inserting that value will reproduce the error consistently during any theme change.

#15 @mtg169
12 months ago

Checking the value I shared, this happens because sidebar-1 is null:

s:9:\"sidebar-1\";N;

Why some widgets may get stored as null values is unknown, but if core properly handled unexpected data types in the sidebars_widgets option and converted any null value to an empty array before calling array functions, it would prevent fatals.

#16 @SirLouen
8 months ago

#63579 was marked as a duplicate.

#17 @audrasjb
8 months ago

  • Milestone set to Awaiting Review

Moving to the Awaiting Review queue list instead of no milestone, since it has been reopened.

#18 @audrasjb
8 months ago

  • Keywords needs-patch added; has-patch has-unit-tests removed

This ticket was mentioned in PR #9603 on WordPress/wordpress-develop by @lakshyajeet.


6 months ago
#19

  • Keywords has-patch added; needs-patch removed

Trac ticket: https://core.trac.wordpress.org/ticket/57469

The PR ensures that any NULL values in the sidebars_widgets array are replaced with empty arrays during widget retrieval and mapping.

This is needed as PHP 8.x introduces stricter type and warning behaviors that can break assumptions made in earlier versions.

Code used to testing:

DELETE FROM `wp_options` WHERE `option_name` = 'sidebars_widgets';
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('sidebars_widgets','a:2:{s:19:"wp_inactive_widgets";N;s:9:"sidebar-1";N;}','yes');

### Before:

https://github.com/user-attachments/assets/6e575c6f-7bc4-4682-b55a-00d6cc05c141

### After:

https://github.com/user-attachments/assets/4342d7d6-4f6c-4e8e-84c1-ab25e6d58eec

@lakshyajeet
6 months ago

Before the fix

@lakshyajeet
6 months ago

After the fix

#20 follow-up: @mindctrl
6 months ago

  • Keywords needs-unit-tests needs-testing added

@lakshyajeet could you add some unit tests for this to confirm desired behavior and to prevent regressions?

#21 in reply to: ↑ 20 @lakshyajeet
6 months ago

Replying to mindctrl:

Yeah sure, I'll add some unit tests.

#22 @lakshyajeet
6 months ago

@mindctrl I have added the tests.

@mindctrl commented on PR #9603:


5 months ago
#23

@DarkMatter-999 thanks for adding phpunit tests.

Here's my test report for this PR:

## Test Report
### Description
This report validates whether the indicated patch works as expected.

Patch tested: https://github.com/WordPress/wordpress-develop/pull/9603

### Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.29
  • Server: nginx/1.29.0
  • Database: mysqli (Server: 8.4.6 / Client: mysqlnd 8.2.29)
  • Browser: Chrome 140.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins:
    • phpmailer.php
  • Plugins:
    • Test Reports 1.2.0

### Actual Results

  1. ✅ Issue resolved with patch.

### Additional Notes

  • Without this patch, once the fatal error happens, the site is inoperable until a manual fix is applied.
  • Since it's unclear how the sidebar widgets get set to null in some cases, I manually created wp_options.sidebars_widgets with a sidebar containing a null value using the MySQL commands in the description above.

#### Delete existing config

mysql> DELETE FROM `wp_options` WHERE `option_name` = 'sidebars_widgets';
Query OK, 1 row affected (0.00 sec)

#### Insert config with null values

mysql> INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('sidebars_widgets','a:2:{s:19:"wp_inactive_widgets";N;s:9:"sidebar-1";N;}','yes');
Query OK, 1 row affected (0.00 sec)

#### Get config to confirm new values

mysql> select * from wp_options where option_name = 'sidebars_widgets';
+-----------+------------------+-------------------------------------------------------+----------+
|| option_id || option_name      || option_value                                          || autoload ||
+-----------+------------------+-------------------------------------------------------+----------+
||       175 || sidebars_widgets || a:2:{s:19:"wp_inactive_widgets";N;s:9:"sidebar-1";N;} || yes      ||
+-----------+------------------+-------------------------------------------------------+----------+
1 row in set (0.00 sec)

#### Get config after switching themes in wp-admin

mysql> select * from wp_options where option_name = 'sidebars_widgets';
+-----------+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
|| option_id || option_name      || option_value                                                                                                                                                                                                                                                             || autoload ||
+-----------+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
||       175 || sidebars_widgets || a:7:{s:19:"wp_inactive_widgets";a:5:{i:0;s:7:"block-2";i:1;s:7:"block-3";i:2;s:7:"block-4";i:3;s:7:"block-5";i:4;s:7:"block-6";}s:9:"sidebar-1";a:0:{}s:9:"sidebar-2";a:0:{}s:9:"sidebar-3";a:0:{}s:9:"sidebar-4";a:0:{}s:9:"sidebar-5";a:0:{}s:13:"array_version";i:3;} || yes      ||
+-----------+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
1 row in set (0.00 sec)

mysql> 

#24 @mindctrl
5 months ago

  • Keywords has-unit-tests added; needs-unit-tests needs-testing removed

Unit tests were added by @lakshyajeet in the PR: https://github.com/WordPress/wordpress-develop/pull/9603.

My test report was added there also.

#25 @pmbaldha
5 months ago

Test Report

✅ The test report validates that the issue can be reproduced in the current Trunk branch and the patch is resolving the fatal error.

Patch tested: https://github.com/WordPress/wordpress-develop/pull/9603

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.29
  • Server: nginx/1.29.1
  • Database: mysqli (Server: 8.4.6 / Client: mysqlnd 8.2.29)
  • Browser: Chrome 140.0.0.0
  • OS: Windows 10/11
  • Theme: Twenty Seventeen 3.9
  • MU Plugins:
    • test.php
  • Plugins:
    • Test Reports 1.2.0

Steps to Reproduce or Test

  1. Setup a WordPress website.
  2. Open PHPMyAdmin and run the below SQL queries:

DELETE FROM wp_options WHERE option_name = 'sidebars_widgets';
INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('sidebars_widgets','a:2:{s:19:"wp_inactive_widgets";N;s:9:"sidebar-1";N;}','yes');

  1. 🐞 Open the Admin Dashboard and you will face the error as below:

Fatal error: Uncaught TypeError: array_merge(): Argument #2 must be of type array, null given in /var/www/src/wp-includes/widgets.php:1354 Stack trace: #0 /var/www/src/wp-includes/widgets.php(1354): array_merge(Array, NULL, Array, Array) #1 /var/www/src/wp-includes/widgets.php(1299): retrieve_widgets(true) #2 /var/www/src/wp-includes/class-wp-hook.php(326): _wp_sidebars_changed('Twenty Nineteen') #3 /var/www/src/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #4 /var/www/src/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #5 /var/www/src/wp-includes/theme.php(3504): do_action('after_switch_th...', 'Twenty Nineteen', Object(WP_Theme)) #6 /var/www/src/wp-includes/class-wp-hook.php(324): check_theme_switched() #7 /var/www/src/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #8 /var/www/src/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #9 /var/www/src/wp-settings.php(728): do_action('init') #10 /var/www/wp-config.php(107): require_once('/var/www/src/wp...') #11 /var/www/src/wp-load.php(55): require_once('/var/www/wp-con...') #12 /var/www/src/wp-admin/admin.php(35): require_once('/var/www/src/wp...') #13 /var/www/src/wp-admin/_index.php(10): require_once('/var/www/src/wp...') #14 /var/www/src/wp-admin/index.php(10): require_once('/var/www/src/wp...') #15 {main} thrown in /var/www/src/wp-includes/widgets.php on line 1354

Expected Results

When testing a patch to validate it works as expected:

  • ✅ The Admin Dashboard should load without any fatal error.

When reproducing a bug:

  • 🐞 Open the Admin Dashboard and you will face the error as below:

Fatal error: Uncaught TypeError: array_merge(): Argument #2 must be of type array, null given in /var/www/src/wp-includes/widgets.php:1354 Stack trace: #0 /var/www/src/wp-includes/widgets.php(1354): array_merge(Array, NULL, Array, Array) #1 /var/www/src/wp-includes/widgets.php(1299): retrieve_widgets(true) #2 /var/www/src/wp-includes/class-wp-hook.php(326): _wp_sidebars_changed('Twenty Nineteen') #3 /var/www/src/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #4 /var/www/src/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #5 /var/www/src/wp-includes/theme.php(3504): do_action('after_switch_th...', 'Twenty Nineteen', Object(WP_Theme)) #6 /var/www/src/wp-includes/class-wp-hook.php(324): check_theme_switched() #7 /var/www/src/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #8 /var/www/src/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #9 /var/www/src/wp-settings.php(728): do_action('init') #10 /var/www/wp-config.php(107): require_once('/var/www/src/wp...') #11 /var/www/src/wp-load.php(55): require_once('/var/www/wp-con...') #12 /var/www/src/wp-admin/admin.php(35): require_once('/var/www/src/wp...') #13 /var/www/src/wp-admin/_index.php(10): require_once('/var/www/src/wp...') #14 /var/www/src/wp-admin/index.php(10): require_once('/var/www/src/wp...') #15 {main} thrown in /var/www/src/wp-includes/widgets.php on line 1354

Actual Results

When reproducing a bug/defect:

  • 🐞 The Fatal error occurs.

Fatal error: Uncaught TypeError: array_merge(): Argument #2 must be of type array, null given in /var/www/src/wp-includes/widgets.php:1354 Stack trace: #0 /var/www/src/wp-includes/widgets.php(1354): array_merge(Array, NULL, Array, Array) #1 /var/www/src/wp-includes/widgets.php(1299): retrieve_widgets(true) #2 /var/www/src/wp-includes/class-wp-hook.php(326): _wp_sidebars_changed('Twenty Nineteen') #3 /var/www/src/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #4 /var/www/src/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #5 /var/www/src/wp-includes/theme.php(3504): do_action('after_switch_th...', 'Twenty Nineteen', Object(WP_Theme)) #6 /var/www/src/wp-includes/class-wp-hook.php(324): check_theme_switched() #7 /var/www/src/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #8 /var/www/src/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #9 /var/www/src/wp-settings.php(728): do_action('init') #10 /var/www/wp-config.php(107): require_once('/var/www/src/wp...') #11 /var/www/src/wp-load.php(55): require_once('/var/www/wp-con...') #12 /var/www/src/wp-admin/admin.php(35): require_once('/var/www/src/wp...') #13 /var/www/src/wp-admin/_index.php(10): require_once('/var/www/src/wp...') #14 /var/www/src/wp-admin/index.php(10): require_once('/var/www/src/wp...') #15 {main} thrown in /var/www/src/wp-includes/widgets.php on line 1354

When testing the bugfix patch:

  • ✅ The Fatal error resolved with the patch.

#26 @westonruter
5 months ago

  • Keywords commit added
  • Milestone changed from Awaiting Review to 6.9
  • Owner set to westonruter
  • Status changed from reopened to accepted

#27 @westonruter
5 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 60732:

Widgets: Prevent fatal errors in PHP 8 when retrieve_widgets() and wp_map_sidebars_widgets() attempt to merge non-array values.

Props kesselb, lakshyajeet, hellofromTonya, janthiel, ikriv, audrasjb, mtg169, bartnv, pmbaldha, mindctrl, westonruter, jrf.
Fixes #57469.

Note: See TracTickets for help on using tickets.