Commit b882e149e72 for woocommerce

commit b882e149e724c145fddc248d4fe49520367b56b4
Author: Michal Iwanow <4765119+mcliwanow@users.noreply.github.com>
Date:   Wed Nov 4 13:58:33 2026 +0100

    Ignore unused variation attributes when adding to the cart (#70633)

    The cart keeps only the attributes the parent product uses for variations, and the meta box tab script looks up panels with $( document ).find().

    Co-authored-by: Tung Du <5423135+dinhtungdu@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/fix-cart-variation-attributes b/plugins/woocommerce/changelog/fix-cart-variation-attributes
new file mode 100644
index 00000000000..c6f997a3d1f
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-cart-variation-attributes
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+When a shopper adds a product to the cart, ignore attributes that the product does not use.
diff --git a/plugins/woocommerce/client/legacy/js/admin/meta-boxes.js b/plugins/woocommerce/client/legacy/js/admin/meta-boxes.js
index 244f5593c4a..6291466912a 100644
--- a/plugins/woocommerce/client/legacy/js/admin/meta-boxes.js
+++ b/plugins/woocommerce/client/legacy/js/admin/meta-boxes.js
@@ -127,7 +127,14 @@ jQuery( function ( $ ) {
 				$( 'ul.wc-tabs li', panel_wrap ).removeClass( 'active' );
 				$( this ).parent().addClass( 'active' );
 				$( 'div.panel', panel_wrap ).hide();
-				$( $( this ).attr( 'href' ) ).show( 0, function () {
+				// Look up the panel by the link's selector. A selector that is not valid finds nothing.
+				var panel;
+				try {
+					panel = $( document ).find( $( this ).attr( 'href' ) || '' );
+				} catch ( error ) {
+					panel = $();
+				}
+				panel.show( 0, function () {
 					$( this ).trigger( 'woocommerce_tab_shown' );
 				} );
 			} );
diff --git a/plugins/woocommerce/includes/class-wc-cart.php b/plugins/woocommerce/includes/class-wc-cart.php
index e61e8d60ba4..8332d29a94e 100644
--- a/plugins/woocommerce/includes/class-wc-cart.php
+++ b/plugins/woocommerce/includes/class-wc-cart.php
@@ -1314,9 +1314,10 @@ class WC_Cart extends WC_Legacy_Cart {
 					} elseif ( '' === $valid_value ) {
 						$missing_attributes[] = wc_attribute_label( $attribute['name'] );
 					}
-
-					$variation = $attributes;
 				}
+
+				// Keep only the checked attributes. This also drops posted values when the parent has no variation attributes.
+				$variation = $attributes;
 				if ( ! empty( $missing_attributes ) ) {
 					/* translators: %s: Attribute name. */
 					throw new Exception( sprintf( _n( '%s is a required field', '%s are required fields', count( $missing_attributes ), 'woocommerce' ), wc_format_list_of_items( $missing_attributes ) ) );
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
index 3eeb423a6f8..7433577dcc6 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
@@ -2844,6 +2844,61 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
 		$this->assertEquals( $variation['variation_id'], $this->add_to_cart_quantity_filter_args[2] );
 	}

+	/**
+	 * @testdox Adding a variation to the cart keeps only the attributes its parent uses for variations.
+	 * @dataProvider parent_variation_attribute_provider
+	 *
+	 * @param bool  $used_for_variations Whether the parent's Color attribute is ticked "Used for variations".
+	 * @param array $expected            The variation data the cart item should keep.
+	 */
+	public function test_add_to_cart_keeps_only_parent_variation_attributes( bool $used_for_variations, array $expected ): void {
+		$attribute = new WC_Product_Attribute();
+		$attribute->set_name( 'Color' );
+		$attribute->set_options( array( 'Red', 'Blue' ) );
+		$attribute->set_variation( true );
+
+		$product = new WC_Product_Variable();
+		$product->set_attributes( array( $attribute ) );
+		$product->save();
+
+		$variation = new WC_Product_Variation();
+		$variation->set_parent_id( $product->get_id() );
+		$variation->set_attributes( array( 'color' => 'Red' ) );
+		$variation->set_regular_price( '10' );
+		$variation->save();
+
+		// Save the parent again with the box ticked or unticked. Unticking it leaves the variation published and for sale.
+		$attribute = clone $attribute;
+		$attribute->set_variation( $used_for_variations );
+		$product->set_attributes( array( $attribute ) );
+		$product->save();
+
+		$cart_item_key = WC()->cart->add_to_cart(
+			$variation->get_id(),
+			1,
+			0,
+			array(
+				'attribute_color' => 'Red',
+				'attribute_x'     => 'not an option of this product',
+			)
+		);
+
+		$this->assertNotFalse( $cart_item_key );
+		$this->assertSame( $expected, WC()->cart->get_cart_item( $cart_item_key )['variation'] );
+	}
+
+	/**
+	 * Provides whether the parent uses Color for variations, and the variation data the cart should keep.
+	 *
+	 * @return array<string, array{bool, array<string, string>}>
+	 */
+	public static function parent_variation_attribute_provider(): array {
+		return array(
+			'parent uses Color for variations'        => array( true, array( 'attribute_color' => 'Red' ) ),
+			'parent uses no attribute for variations' => array( false, array() ),
+		);
+	}
+
 	/**
 	 * @testdox woocommerce_add_to_cart_quantity filter should receive 0 as variation_id when a simple product is added to cart.
 	 */