5

/wp-includes/class-wp-widget.php gives me an error for one blog, but not the other, and both have the same version of class-wp-widget.php which makes no sense to me.

PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function WP_Widget::__construct(), 0 passed in /home/www/stackexchange.com/wp-includes/class-wp-widget-factory.php on line 61 and at least 2 expected in /home/www/stackexchange.com/wp-includes/class-wp-widget.php:162

Reading the code, it appears class-wp-widget.php is the root of the problem, but I could be wrong.

My other (working) blog on the same server has this same file and I don't get the error.

You can see the broken WordPress function here https://developer.wordpress.org/reference/classes/wp_widget/__construct/

Is there a way to "turn off" widgets to deactivate this broken WordPress code?

Update: thanks @bosco for the idea, looking at the Stack trace helped...

Stack trace:
#0 /home/www/example.com/wp-includes/class-wp-widget-factory.php(61): WP_Widget->__construct()
#1 /home/www/example.com/wp-includes/widgets.php(115): WP_Widget_Factory->register()
#2 /home/www/example.com/wp-content/themes/theme1516/includes/register-widgets.php(22): register_widget()
#3 /home/www/example.com/wp-includes/class-wp-hook.php(307): load_my_widgets()
#4 /home/www/example.com/wp-includes/class-wp-hook.php(331): WP_Hook->apply_filters()
#5 /home/www/example.com/wp-includes/plugin.php(476): WP_Hook->do_action()
#6 /home/www/example.com/wp-includes/widgets.php(1854)

Since "register-widgets.php" is the only non-core code here, and because I assume @bosco's comment is correct, I commented out the old widgets and that at least removed the "white screen of death" meanwhile the homepage looks wonky, will probably just cut/paste the HTML from the PHP 7.x site.

8
  • 4
    If it were a PHP 8.1 compatibility issue, I'd wager you'd be seeing a deprecation notice instead - per Make: "All remaining known PHP 8.1 issues are deprecation notices.". More than likely, this error is the product of a plugin or theme using a long outmoded Widget registration method - that the call stack in the error does not mention an extension does not mean the error was not caused by one. The traditional troubleshooting method of disabling/enabling one by one could help to identify the culprit
    – bosco
    Commented May 30, 2022 at 23:47
  • 1
    Reading through the code myself, it looks like an extension is probably passing something to register_widget() that does not properly override the WP_Widget constructor.
    – bosco
    Commented May 30, 2022 at 23:59
  • 1
    I'd wait before upgrading to PHP 8.1, while WordPress will run on PHP 8.0 it still doesn't officially support 8.0, and many plugins and themes haven't been tested or work on 8.0. 8.1 is even newer still, and a lot of the tooling hasn't been updated to run on it yet. At least for a few more months you should consider 8.1 bleeding edge. As long as you're on a version of PHP that's still within its support window you'll be ok for now
    – Tom J Nowell
    Commented May 31, 2022 at 0:00
  • Otherwise Bosco is probably right, deactivate all plugins and turn them back on one by one, and then look through that plugin for its widget registration calls, a stack trace would have pointed directly to the relevant plugin though. The error you shared just indicates it's Widget related, most likely a custom widget is trying to call the parent constructor but not passing any arguments, like this: parent::__construct() when it's supposed to be like this parent::__construct( 'my_widget', 'My Widget' );
    – Tom J Nowell
    Commented May 31, 2022 at 0:02
  • OK @bosco I'm going to try it again, I found some old register_widget calls in an old theme, maybe I can comment those out.
    – Jay Brunet
    Commented May 31, 2022 at 0:10

3 Answers 3

16

In case you couldn’t revert to PHP older than 8.1 or fix the widget registration (and you trust your 10+ years old theme), you can update the line 61 of wp-includes/class-wp-widget-factory.php this way :

$this->widgets[ $widget ] = new $widget( $widget, $widget );

This may fix the widget registration.

4
  • 2
    This was exactly my issue too and this code change resolved it for me. Thank you so much for this!
    – SqlRyan
    Commented Feb 6, 2023 at 16:09
  • Thanks. That saved my bacon.
    – recantha
    Commented May 16, 2023 at 19:28
  • That was incredible! After making that little change I could start WordPress and then easily deactivate the problematic plugin. Then I could change the code back again to the default WordPress code ($this->widgets[ $widget ] = new $widget()), and the website still works. Thank you so much!
    – Jesper
    Commented Jul 29, 2023 at 16:35
  • 1
    Friendly reminder that modifying core is never a great idea. You do one update and poof, it needs to be done again.
    – Fredy31
    Commented Aug 17, 2023 at 19:38
2

I suspect the cause is a custom widget that has been built incorrectly. Take a look at this example from the Codex:

class My_Widget extends WP_Widget {

    /**
     * Sets up the widgets name etc
     */
    public function __construct() {
        $widget_ops = array( 
            'classname' => 'my_widget',
            'description' => 'My Widget is awesome',
        );
        parent::__construct( 'my_widget', 'My Widget', $widget_ops );
    }

What a lot of poorly built plugins do is this:

class My_Widget extends WP_Widget {

    /**
     * Sets up the widgets name etc
     */
    public function __construct() {
        parent::__construct();
    }

Or they fail to include a __construct method at all! Passing no parameters or not having a constructor is incorrect. Past versions of PHP may have substituted these values for null or undefined, resolving to ''`, but I would still have expected this to become a problem before upgrading to 8.1, and it would certainly have appeared in the error log as a notice.

So identify which plugin or theme is responsible for this, either with stack traces, or a process of elimination, perhaps even by doing a search of the codebase with a tool.

If this is in code that you maintain such as a custom theme or plugin, you can resolve the issue by implementing the Widget API correctly as the Codex and the devhub handbooks instruct. Specifically, by providing the first two parameters.

If you're not interested in fixing the widgets, you can also remove them from your site completely.


In the meantime, downgrade to 8.0 for a little while. Both 8.0 and 8.1 are currently supported versions of PHP and receiving updates. WordPress has yet to build official support for 8.0, and 8.1 is a very recent release ( early 2022 ), so it's unsurprising you encountered compatibility issues and clashes with 3rd party code when you upgraded.

5
  • While I appreciate the effort, this answer resembles other answers I found in Google. In my particular case, I'm not using the widgets, they were just included as extras in the theme, and I have no desire to fix a dozen old widgets from 10+ years ago. As for PHP 8.x I have two test blogs running it fine on Arch, BTW ;-)
    – Jay Brunet
    Commented May 31, 2022 at 0:42
  • 2
    wether you used the widgets or not is irrelevant to the problem ( I'm running my own site on 8.0 ). If you don't intend to use the widgets and don't want to fix them, then you should remove them. The problem is not WordPress, it's 3rd party code misusing the API generating errors.
    – Tom J Nowell
    Commented May 31, 2022 at 0:52
  • To put it another way, when your code written depending on a library written for the C++ 98 standard won't compile when you update your code to the C++ 20 standard, it's not remotely the fault of the C++ Comittee/Working Group - you're trying to use a library that some schmuck wrote more than 20 years ago and never updated on a platform that was never built to facilitate it. WordPress has an annoyingly strong conviction when it comes to backwards compatibility - but breaking changes are good for the health and development of any technology.
    – bosco
    Commented May 31, 2022 at 19:31
  • 1
    Whereas in this case the Widget was built incorrectly on day 1
    – Tom J Nowell
    Commented May 31, 2022 at 19:34
  • @TomJNowell These things happen, but PHP 8.x seems more picky than previous versions. I found other fatal errors, but fortunately they were fixed in WP 6.
    – Jay Brunet
    Commented Jun 1, 2022 at 22:33
1

For anyone still having this issue, you can try to go wordpress/wp-includes/class-wp-widget-factory.php on line 61 make this change to fix the issue without changing any other code:

Change this: $this->widgets[ $widget ] = new $widget();

To: $this->widgets[ $widget ] = new $widget( $widget, $widget );

Everything should work as expected now.

3
  • 2
    No, don't edit core files, ever.
    – vancoder
    Commented Jan 19, 2023 at 22:40
  • 2
    For sure it's a bad idea and you shouldn't make this change and then just walk away, but when your site won't load and you can't even export or recover it because the admin interface is unavailable, this is a huge help.
    – SqlRyan
    Commented Feb 6, 2023 at 16:16
  • 1
    in the March 2023 Wordpress update (6.2) there is still an incompatibility with PHP 8.1 version which still has to be solved this way... :/ (yes, this file is overwritten after each update) Commented Apr 10, 2023 at 13:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.