#1140116 wordpress: Multisite Add User fatals with “Skip Confirmation Email”

#1140116#5
Date:
2026-06-16 01:24:37 UTC
From:
To:
Dear Maintainer,

wordpress 6.9.4+dfsg1-1:
In Wordpress with multisite enabled, with superadmin on any site, add a new user with skip confirmation email and it will error:
“Skip Confirmation Email” fatals in wp-admin/user-new.php.

The code in question only gets triggered in teh skip confirmation email pathway.

[15-Jun-2026 23:36:08 UTC] PHP Fatal error: Uncaught Error: Cannot use object of type stdClass as array in /usr/share/wordpress/wp-admin/user-new.php:244 Stack trace: #0 {main} thrown in /usr/share/wordpress/wp-admin/user-new.php on line 244

In that area of code:
$wpdb->get_row() returns stdClass by default, but Debian-patched
user-new.php line 244 accesses the result as an array:

$row['activation_key']
$row['signup_id']

Fatal:
Cannot use object of type stdClass as array


This appears to be a regression introduced by Debian's downstream `38474.patch`, rather than by WordPress 6.9 itself.

The same faulty hunk is present in Debian's WordPress 6.8.3 package, and the patch metadata lists `Last-Update: 2023-08-10`. It may have affected Debian WordPress packages since the 6.3-era update in August 2023 although I have not confirmed this.

The issue is also present in the newly uploaded Debian unstable package wordpress 7.0+dfsg1-1. Its debian/patches/38474.patch still changes wp-admin/user-new.php in the same way.



Changing these to:
$row->activation_key
$row->signup_id

fixes the error.

#1140116#10
Date:
2026-06-16 03:03:11 UTC
From:
To:
Further investigation shows that correcting the stdClass array access
does not fully resolve the problem.

After changing:

$row['activation_key']
$row['signup_id']

to object access, the fatal no longer occurs, but the user is still not
created.

The call to wpmu_activate_signup() returns:

expired_key
Invalid key

For example:

   root@web2:~# runuser -u www-data -- wp db query "
   SELECT
       signup_id,
       user_login,
       user_email,
       registered,
       activated,
       active,
       activation_key,
       meta
   FROM wp_signups
   ORDER BY registered DESC;
   "   --path=/usr/share/wordpress
   PHP Warning:  Undefined array key "HTTP_HOST" in
   phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1334)
   : eval()'d code on line 10
   signup_id	user_login	user_email	registered	activated
   	active	activation_key	meta
   4	testuser4	testuser4@test.com	2026-06-16
   01:36:41	0000-00-00 00:00:00	0	1781573801:$P$BxtQL25BC9z9l4e5zaK5VZlU9xkF8o1	a:2:{s:11:"add_to_blog";i:1;s:8:"new_role";s:10:"subscriber";}
   3	testuser3	testuser3@arctic.network	2026-06-16
   01:09:37	0000-00-00
   00:00:00	0	1781572177:$P$Ba8H1ph.D2fsdaYhgEP.GkpFAsey06.a:2:{s:11:"add_to_blog";i:1;s:8:"new_role";s:10:"subscriber";}
   2	testuser2	testuser2@test.com	2026-06-16
   00:48:28	0000-00-00 00:00:00	0	1781570908:$P$BwBKwX5zVA/Um37UbDA.Vl/k04Vor3/	a:2:{s:11:"add_to_blog";i:1;s:8:"new_role";s:10:"subscriber";}
   1	testuser1	testuser1@test.com	2026-06-15
   23:36:08	0000-00-00 00:00:00	0	1781566568:$P$B0kP7yFpwhQlDfbkvrKCqN0PIrZHQy0	a:2:{s:11:"add_to_blog";i:1;s:8:"new_role";s:10:"subscriber";}





   root@web2:~# runuser -u www-data -- wp eval '
   global $wpdb;

   $row = $wpdb->get_row(
       "SELECT signup_id, activation_key
        FROM {$wpdb->signups}
        WHERE user_login = '\''testuser4'\''"
   );

   $result = wpmu_activate_signup(
       $row->activation_key,
       $row->signup_id
   );

   if ( is_wp_error( $result ) ) {
       echo $result->get_error_code() . PHP_EOL;
       echo $result->get_error_message() . PHP_EOL;
   } else {
       var_dump( $result );
   }
   '   --url=web2.site01.arc   --path=/usr/share/wordpress

   expired_key
   Invalid key



The corresponding row remains in wp_signups with:

active = 0
activated = 0000-00-00 00:00:00

and no user is added to wp_users.

The activation_key stored in wp_signups has the timestamped hashed
form:

<timestamp>:$P$<hash>

The patched wp-admin/user-new.php retrieves this stored value and
passes it to wpmu_activate_signup(). The patched activation function
then rejects it because the supplied value exactly matches the stored
activation_key.

Despite the failed activation, the admin interface displays:

"User has been added to your site."

Therefore, the original stdClass fatal is only the first visible
failure. The same workflow also leaves a pending signup, does not
create the user, and displays a misleading success message.

In terms of a patch for this then, I'm not sure which way to go. I
haven't looked deeply into the history of the debian patch....

the patch alters 4 files:
   wp-activate.php
   wp-admin/user-new.php
   wp-includes/ms-default-filters.php
   wp-includes/ms-functions.php

So this patch is in context to an Upstream WordPress ticket #38474 that
identified that anyone with read access to the database could retrieve
unused activation links directly. Debian carries that proposed upstream
patch as a security fix for CVE-2017-14990.

So likely both ms-functions.php and user-new.php will need quite a few
modifications....

#1140116#15
Date:
2026-06-19 08:12:54 UTC
From:
To:
I've reached out to the WordPress security team and they're looking into it.
It could be hopefully that this patch or something that does the same thing
will be incorporated.

For the current error, try changing thing["item"] to thing->item

I'll either make those changes to the Debian package or wait for the next
WordPress release depending on how soon it is.

 - Craig

#1140116#20
Date:
2026-06-25 10:20:01 UTC
From:
To:
Changing thing["item"] to thing->item did get past the initial error,
but unearth other problems with that code path in general for the
debian patch "38474.patch".

I actually have a reasonably full patch (attached) that is looking
quite robust. I was hoping to also attach a sane and readable list of
some wpcli based tests before I submitted the patch but I haven't got
those together yet....


Adrian