Make WordPress Core

Opened 16 months ago

Last modified 5 weeks ago

#62950 new defect (bug)

PHP deprecation warning in /wp-admin/includes/class-automatic-upgrader-skin.php

Reported by: nexbridge's profile nexbridge Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.7.2
Component: Upgrade/Install Keywords: has-patch
Focuses: Cc:

Description

The following warnings are being triggered in the above file when the WordPress version auto-updates.

On line 87:

str_contains(): Passing null to parameter #1 ($haystack) of type string is deprecated

On line 93:

trim(): Passing null to parameter #1 ($string) of type string is deprecated

The PHP version is 8.2.

Attachments (1)

62950.patch (634 bytes) - added by sainathpoojary 16 months ago.
The issue occurred because $string was uninitialized when $feedback was neither an error nor a string, resulting in null being passed to str_contains() and trim(), which is deprecated in PHP 8.2. This fix ensures $string is always initialized as an empty string before use, preventing these warnings.

Download all attachments as: .zip

Change History (9)

@sainathpoojary
16 months ago

The issue occurred because $string was uninitialized when $feedback was neither an error nor a string, resulting in null being passed to str_contains() and trim(), which is deprecated in PHP 8.2. This fix ensures $string is always initialized as an empty string before use, preventing these warnings.

#1 @nexbridge
16 months ago

Thanks @sainathpoojary, but in PHP if a variable is not initialised then it would throw a different warning - the issue here seems to be that the variable is being set to NULL in some cases and this is then causing the deprecation warning when it's passed into str_contains() or trim(). The variable is being set on lines 76, 80 and 84, however judging by the code I doubt that lines 76 or 84 would return a NULL value, so it may be as simple as just adding a null coalescing operator on line 80:

<?php
$string = $feedback ?? '';

To that end I've added some debug lines to test my theory the next time it happens!

#2 @sainathpoojary
16 months ago

Thanks for the clarification! You’re right if the variable were truly uninitialized, we’d expect a different warning. It makes sense that $feedback might explicitly be null in some cases, leading to the deprecation warning when passed into str_contains() or trim(). I’ll test the fix with auto-updates, and if it works as expected, I’ll raise a PR. 🚀

#3 @nexbridge
4 months ago

Just to say that this is still happening on the 6.9 branch. I've included stack traces for both the trim() and str_contains() warnings if it helps.

[2026-02-04 04:38:00] str_contains(): Passing null to parameter #1 ($haystack) of type string is deprecated
E_DEPRECATED at /wp-admin/includes/class-automatic-upgrader-skin.php(87):
#0 [internal function]: {closure}()
#1 /wp-admin/includes/class-automatic-upgrader-skin.php(87): str_contains()
#2 /wp-includes/class-wp-hook.php(341): Automatic_Upgrader_Skin->feedback()
#3 /wp-includes/plugin.php(205): WP_Hook->apply_filters()
#4 /wp-admin/includes/update-core.php(1577): apply_filters()
#5 /wp-admin/includes/class-core-upgrader.php(178): update_core()
#6 /wp-admin/includes/class-wp-automatic-updater.php(478): Core_Upgrader->upgrade()
#7 /wp-admin/includes/class-wp-automatic-updater.php(715): WP_Automatic_Updater->update()
#8 /wp-includes/update.php(890): WP_Automatic_Updater->run()
#9 /wp-includes/class-wp-hook.php(341): wp_maybe_auto_update()
#10 /wp-includes/class-wp-hook.php(365): WP_Hook->apply_filters()
#11 /wp-includes/plugin.php(522): WP_Hook->do_action()
#12 /wp-content/plugins/stops-core-theme-and-plugin-updates/includes/MPSUM_Disable_Updates.php(191): do_action()
#13 /wp-includes/class-wp-hook.php(341): MPSUM_Disable_Updates->maybe_auto_update()
#14 /wp-includes/class-wp-hook.php(365): WP_Hook->apply_filters()
#15 /wp-includes/plugin.php(570): WP_Hook->do_action()
#16 /wp-cron.php(191): do_action_ref_array()
#17 {main}
[2026-02-04 04:38:00] trim(): Passing null to parameter #1 ($string) of type string is deprecated
E_DEPRECATED at /wp-admin/includes/class-automatic-upgrader-skin.php(93):
#0 [internal function]: {closure}()
#1 /wp-admin/includes/class-automatic-upgrader-skin.php(93): trim()
#2 /wp-includes/class-wp-hook.php(341): Automatic_Upgrader_Skin->feedback()
#3 /wp-includes/plugin.php(205): WP_Hook->apply_filters()
#4 /wp-admin/includes/update-core.php(1577): apply_filters()
#5 /wp-admin/includes/class-core-upgrader.php(178): update_core()
#6 /wp-admin/includes/class-wp-automatic-updater.php(478): Core_Upgrader->upgrade()
#7 /wp-admin/includes/class-wp-automatic-updater.php(715): WP_Automatic_Updater->update()
#8 /wp-includes/update.php(890): WP_Automatic_Updater->run()
#9 /wp-includes/class-wp-hook.php(341): wp_maybe_auto_update()
#10 /wp-includes/class-wp-hook.php(365): WP_Hook->apply_filters()
#11 /wp-includes/plugin.php(522): WP_Hook->do_action()
#12 /wp-content/plugins/stops-core-theme-and-plugin-updates/includes/MPSUM_Disable_Updates.php(191): do_action()
#13 /wp-includes/class-wp-hook.php(341): MPSUM_Disable_Updates->maybe_auto_update()
#14 /wp-includes/class-wp-hook.php(365): WP_Hook->apply_filters()
#15 /wp-includes/plugin.php(570): WP_Hook->do_action()
#16 /wp-cron.php(191): do_action_ref_array()
#17 {main}

#4 @nexbridge
3 months ago

Just to add that I've confirmed it's line 80 that's setting a NULL value for $string, implying that the $feedback argument being passed into the feedback() function is NULL.

#5 @sabernhardt
3 months ago

Something else is setting a null value earlier. It runs through the update_feedback filter before reaching Automatic_Upgrader_Skin::feedback(). Easy Updates Manager lets any non-string pass through its set_core_update_notes because the author(s) knew it could be a WP_Error object.

However, Automatic_Upgrader_Skin::feedback() only supports string, array, or WP_Error.

If merely silencing the deprecation notice is acceptable, the conditions could be rearranged:

if ( is_wp_error( $feedback ) ) {
	$string = $feedback->get_error_message();
} elseif ( is_string( $feedback ) ) {
	$string = $feedback;
} else {
	// Return if $feedback is an array or an unsupported type.
	return;
}
Last edited 3 months ago by sabernhardt (previous) (diff)

#6 @nexbridge
3 months ago

@sabernhardt If that change doesn't break how the function is meant to work then yes that would be fine if simply returning out of the function is an appropriate way of handling the NULL case.

#7 @ankitv
5 weeks ago

The root cause is in the else branch — when $feedback is null, it gets
assigned directly to $string, which then gets passed to str_contains()
and trim(), both triggering PHP 8.2 deprecation warnings.

Fix: cast $feedback to string in the else branch:

$string = (string) $feedback;

This coerces null to at the point of assignment, consistent with the
@param string|array|WP_Error $feedback docblock.

https://github.com/Anny0007/AV-wordpress-develop/pull/1/

#8 @ankitv
5 weeks ago

  • Keywords has-patch added

Could a contributor please update the keywords to has-patch?
Patch is available via PR: https://github.com/Anny0007/AV-wordpress-develop/pull/1/

Note: See TracTickets for help on using tickets.