Index: src/wp-includes/class-wp-customize-manager.php
===================================================================
--- src/wp-includes/class-wp-customize-manager.php	(revision 41242)
+++ src/wp-includes/class-wp-customize-manager.php	(working copy)
@@ -2278,7 +2278,7 @@
 
 		// Amend post values with any supplied data.
 		foreach ( $args['data'] as $setting_id => $setting_params ) {
-			if ( array_key_exists( 'value', $setting_params ) ) {
+			if ( is_array( $setting_params ) && array_key_exists( 'value', $setting_params ) ) {
 				$this->set_post_value( $setting_id, $setting_params['value'] ); // Add to post values so that they can be validated and sanitized.
 			}
 		}
Index: tests/phpunit/tests/customize/manager.php
===================================================================
--- tests/phpunit/tests/customize/manager.php	(revision 41242)
+++ tests/phpunit/tests/customize/manager.php	(working copy)
@@ -1246,6 +1246,37 @@
 	}
 
 	/**
+	 * Test passing `null` for a setting ID to remove it from the changeset.
+	 *
+	 * @covers WP_Customize_Manager::save_changeset_post()
+	 */
+	function test_remove_setting_from_changeset_post() {
+		$uuid = wp_generate_uuid4();
+
+		$manager = $this->create_test_manager( $uuid );
+		$manager->save_changeset_post( array(
+			'data' => array(
+				'scratchpad' => array(
+					'value' => 'foo',
+				),
+			),
+		) );
+
+		// Create a new manager so post values are unset.
+		$manager = $this->create_test_manager( $uuid );
+
+		$this->assertArrayHasKey( 'scratchpad', $manager->changeset_data() );
+
+		$manager->save_changeset_post( array(
+			'data' => array(
+				'scratchpad' => null,
+			),
+		) );
+
+		$this->assertArrayNotHasKey( 'scratchpad', $manager->changeset_data() );
+	}
+
+	/**
 	 * Test writing changesets and publishing with users who can unfiltered_html and those who cannot.
 	 *
 	 * @ticket 38705
