Make WordPress Core

Opened 3 weeks ago

Last modified 11 days ago

#64231 reviewing defect (bug)

Customizer fails to save when switching themes due to an orphaned setting left over from a previously active plugin

Reported by: alessandrolioce's profile alessandrolioce Owned by: westonruter's profile westonruter
Milestone: 7.0 Priority: normal
Severity: normal Version: 6.8.3
Component: Customize Keywords: has-patch has-test-info
Focuses: Cc:

Description

Description

When using the Customizer and switching themes with live preview, WordPress fails to save due to an unrecognized setting.
This happens when a plugin adds a custom setting to the Customizer, then gets deactivated before switching back to another theme.


Environment

  • WordPress v6.8.3
  • Active Theme: Twenty Twenty-One (v2.6)
  • Other used theme Twenty Twenty (v2.9)
  • Plugin: "Adds a testing option in customizer" (used to register “test_orphaned_setting”)


Steps to Reproduce

  1. Activate the plugin that adds a testing option in the Customizer.
  2. Go to Appearance > Customize.
  3. Edit the setting under Site Identity > Test Orphaned Setting.
  4. Without saving, switch to the Twenty Twenty theme using Live Preview, then click Activate & Publish.
  5. Deactivate the plugin (“Adds a testing option in customizer”).
  6. Go to Appearance > Customize again.
  7. Switch the theme back to Twenty Twenty-One using Live Preview.
  8. Click Activate & Publish.


Plugin that adds a testing option

<?php

/**
 * Plugin Name: Adds a testing option in customizer
 */

add_action( 'customize_register', function ( $wp_customize ) {
        $wp_customize->add_setting( 'test_orphaned_setting', array(
                'default'    => '',
                'type'       => 'theme_mod',
                'capability' => 'edit_theme_options',
                'transport'  => 'refresh',
        ) );

        $wp_customize->add_control( 'test_orphaned_setting', array(
                'label'   => 'Test Orphaned Setting',
                'section' => 'title_tagline',
                'type'    => 'text',
        ) );
} );


Observed Behavior

A POST request is sent to /wp-admin/admin-ajax.php with the following parameters:

wp_customize	“on”
customize_theme	“twentytwentyone”
nonce	“d3c3bbbe0e”
customize_changeset_uuid	“b92bc4d4-8665-49df-80ec-52ba9d8ec526”
customize_autosaved	“on”
customized	‘{“old_sidebars_widgets_data”:{“wp_inactive_widgets”:[“block-11”,“block-12”,“block-13”,“block-14”],“sidebar-1”:[“block-2”,“block-3”,“block-4”,“block-5”,“block-6”,“block-7”,“block-8”,“block-9”,“block-10”]},“nav_menu_locations[primary]”:3}’
customize_changeset_status	“publish”
action	“customize_save”
customize_preview_nonce	“bbf9d73816”

The JSON response returns:

{
  "success": false,
  "data": {
    "message": "Unable to save due to 1 invalid setting.",
    "code": "transaction_fail",
    "setting_validities": {
      "test_orphaned_setting": {
        "unrecognized": {
          "message": "Setting does not exist or is unrecognized.",
          "data": null
        }
      },
      "old_sidebars_widgets_data": true,
      "nav_menu_locations[primary]": true
    }
  }
}


Expected Behavior

Customizer should skip unrecognized (orphaned) settings left over from inactive plugins and allow the theme to be saved successfully.


Relevant Code

File: src/wp-includes/class-wp-customize-manager.php

Original Code

if ( isset( $stashed_theme_mods[ $stylesheet ] ) ) {
   $values = array_merge( $values, wp_list_pluck( $stashed_theme_mods[ $stylesheet ], 'value' ) );
}

Proposed fix

if ( isset( $stashed_theme_mods[ $stylesheet ] ) ) {
   $stashed_values = wp_list_pluck( $stashed_theme_mods[ $stylesheet ], 'value' );

   $valid_stashed_values = array_filter( $stashed_values, function ( $setting_id ) {
      return $this->get_setting( $setting_id );
   }, ARRAY_FILTER_USE_KEY );

   $values = array_merge( $values, $valid_stashed_values );
}

Additional Notes

This issue occurs because Customizer stashed theme mods may include references to settings that no longer exist after a plugin deactivation.
The fix ensures only recognized settings are restored, preventing “unrecognized setting” errors and allowing the theme activation to complete successfully.

Change History (3)

This ticket was mentioned in PR #10503 on WordPress/wordpress-develop by alessandrolioce.


3 weeks ago
#1

This PR prevents the Customizer from trying to save unrecognized (orphaned) settings left by deactivated plugins.
It validates stashed theme mods before merging them.

#2 @westonruter
3 weeks ago

  • Milestone changed from Awaiting Review to 7.0
  • Owner set to westonruter
  • Status changed from new to reviewing

#3 @palak678
11 days ago

Tested this on 6.8.3 and below are the results:-

After deactivating the plugin and switching themes back via Customizer, the save request fails.
The response returned 0, confirming the Customizer failed to handle the orphaned setting.

please refer below screenshot:-
https://prnt.sc/aVrVth_jGAuw

Also find below screenshot of return 0 response at /wp-admin/admin-ajax.php?action=customize_save

https://prnt.sc/fhMcPb8snM_x

Note: See TracTickets for help on using tickets.