Skip to content

Admin context should resolve a super admin user on multisite instead of hardcoding user ID 1 #6269

@apermo

Description

@apermo

Bug Report

Describe the current behavior:

When --user is not specified, the Admin context (php/WP_CLI/Context/Admin.php:56) falls back to user ID 1:

// TODO: Add logic to find an administrator user.
$admin_user_id = 1;

On multisite, user ID 1 may not be a super admin (or may not exist at all). This causes commands to silently fail because WordPress core's map_meta_cap() returns do_not_allow for these operations when the current user is not a super admin.

This affects even read-only commands like wp plugin list, because --context=auto now loads the admin environment via wp-admin/plugins.php, which gates access on activate_plugins (line 12). A non-super-admin user on multisite may lack this capability entirely, depending on whether manage_network_plugins is required.

Affected capabilities on multisite (from wp-includes/capabilities.php):

  • activate_plugins — required just to view the plugins page
  • install_plugins, update_plugins, delete_plugins, upload_plugins
  • install_themes, update_themes, delete_themes, upload_themes
  • edit_plugins, edit_themes, edit_files
  • update_core
  • install_languages, update_languages
  • delete_user, delete_users
  • create_users (unless add_new_users site option is set)

Describe the expected behavior:

When no --user is specified and the Admin context is active, WP-CLI should resolve a suitable super admin user on multisite, or a regular administrator on single-site. This aligns with the existing TODO in the code and the principle that CLI tools should work with sensible defaults.

The --user flag already allows impersonating any user, so auto-resolving a super admin does not introduce a new security surface — CLI access already implies full system access.

Steps to reproduce:

  1. Set up a WordPress multisite
  2. Ensure user ID 1 is not a super admin (wp super-admin remove <user-1-login>)
  3. Run wp plugin list (without --user)
  4. The command fails or returns incomplete results due to capability checks
  5. Similarly, wp plugin install hello-dolly fails silently

Environment:

Proposed approach:

Replace the hardcoded fallback with logic that queries get_super_admins() (multisite) or finds a user with the administrator role (single-site). Something like:

if ( is_multisite() ) {
    $super_admins = get_super_admins();
    if ( ! empty( $super_admins ) ) {
        $admin_user = get_user_by( 'login', $super_admins[0] );
        if ( $admin_user ) {
            $admin_user_id = $admin_user->ID;
        }
    }
} else {
    $admins = get_users( array( 'role' => 'administrator', 'number' => 1, 'orderby' => 'ID', 'order' => 'ASC' ) );
    if ( ! empty( $admins ) ) {
        $admin_user_id = $admins[0]->ID;
    }
}

If no suitable user is found, WP-CLI should emit a clear error: Error: No super admin user found. Specify one with --user=<login>.

Related issues:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions