Commit 2ec15024ee7 for woocommerce

commit 2ec15024ee73e153adcbe9242c62a434bfe7e2af
Author: Sanket Parmar <sanket.parmar11@gmail.com>
Date:   Fri Oct 16 14:24:08 2026 +0530

    Show Cart cross-sells add-to-cart errors in the Cart block notices (#69851)

    Show cross-sell add-to-cart errors in Cart block

diff --git a/plugins/woocommerce/changelog/69816-fix-cart-cross-sells-add-error-notice b/plugins/woocommerce/changelog/69816-fix-cart-cross-sells-add-error-notice
new file mode 100644
index 00000000000..003b542dcd1
--- /dev/null
+++ b/plugins/woocommerce/changelog/69816-fix-cart-cross-sells-add-error-notice
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Show an error when a product from the Cart block's cross-sells list cannot be added to the cart, on Cart pages using the cross-sells inner block.
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/test/use-store-add-to-cart.ts b/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/test/use-store-add-to-cart.ts
new file mode 100644
index 00000000000..2ea6d5f5606
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/test/use-store-add-to-cart.ts
@@ -0,0 +1,62 @@
+/**
+ * External dependencies
+ */
+import { act, renderHook } from '@testing-library/react';
+import { useDispatch } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { useStoreAddToCart } from '../use-store-add-to-cart';
+
+jest.mock( '@wordpress/data', () => ( {
+	...jest.requireActual( '@wordpress/data' ),
+	useDispatch: jest.fn(),
+} ) );
+
+jest.mock( '../cart/use-store-cart', () => ( {
+	useStoreCart: () => ( { cartItems: [], cartIsLoading: false } ),
+} ) );
+
+describe( 'useStoreAddToCart', () => {
+	const createErrorNotice = jest.fn();
+
+	beforeEach( () => {
+		createErrorNotice.mockClear();
+		( useDispatch as jest.Mock ).mockReturnValue( {
+			addItemToCart: jest
+				.fn()
+				.mockRejectedValue( new Error( 'Out of stock' ) ),
+			createErrorNotice,
+			removeNotice: jest.fn(),
+		} );
+	} );
+
+	it( 'shows add to cart errors in the All Products context by default', async () => {
+		const { result } = renderHook( () => useStoreAddToCart( 1 ) );
+
+		await act( async () => {
+			await result.current.addToCart();
+		} );
+
+		expect( createErrorNotice ).toHaveBeenCalledWith(
+			'Out of stock',
+			expect.objectContaining( { context: 'wc/all-products' } )
+		);
+	} );
+
+	it( 'shows add to cart errors in the given notice context', async () => {
+		const { result } = renderHook( () =>
+			useStoreAddToCart( 1, 'wc/cart' )
+		);
+
+		await act( async () => {
+			await result.current.addToCart();
+		} );
+
+		expect( createErrorNotice ).toHaveBeenCalledWith(
+			'Out of stock',
+			expect.objectContaining( { context: 'wc/cart' } )
+		);
+	} );
+} );
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/use-store-add-to-cart.ts b/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/use-store-add-to-cart.ts
index a42d55b3491..436718f64b6 100644
--- a/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/use-store-add-to-cart.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/base/context/hooks/use-store-add-to-cart.ts
@@ -43,12 +43,16 @@ const getQuantityFromCartItems = (
  * action for adding a single quantity of the product _to_ the cart.
  *
  *
- * @param {number} productId The product id to be added to the cart.
+ * @param {number} productId     The product id to be added to the cart.
+ * @param {string} noticeContext The notice context that shows add to cart errors.
  *
  * @return {StoreCartItemAddToCart} An object exposing data and actions relating
  *                                  to add to cart functionality.
  */
-export const useStoreAddToCart = ( productId: number ): StoreAddToCart => {
+export const useStoreAddToCart = (
+	productId: number,
+	noticeContext = 'wc/all-products'
+): StoreAddToCart => {
 	const { addItemToCart } = useDispatch( cartStore );
 	const { cartItems, cartIsLoading } = useStoreCart();
 	const { createErrorNotice, removeNotice } = useDispatch( 'core/notices' );
@@ -62,12 +66,12 @@ export const useStoreAddToCart = ( productId: number ): StoreAddToCart => {
 		setAddingToCart( true );
 		return addItemToCart( productId, quantity )
 			.then( () => {
-				removeNotice( 'add-to-cart' );
+				removeNotice( 'add-to-cart', noticeContext );
 			} )
 			.catch( ( error ) => {
 				createErrorNotice( decodeEntities( error.message ), {
 					id: 'add-to-cart',
-					context: 'wc/all-products',
+					context: noticeContext,
 					isDismissible: true,
 				} );
 			} )
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/cart/cart-cross-sells-product-list/cart-cross-sells-product.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/cart/cart-cross-sells-product-list/cart-cross-sells-product.tsx
index e362a5baa89..dd37f9a5e6a 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/cart/cart-cross-sells-product-list/cart-cross-sells-product.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/cart/cart-cross-sells-product-list/cart-cross-sells-product.tsx
@@ -6,6 +6,7 @@ import {
 	ProductDataContextProvider,
 } from '@woocommerce/shared-context';
 import { ProductResponseItem } from '@woocommerce/types';
+import { noticeContexts } from '@woocommerce/base-context';

 /**
  * Internal dependencies
@@ -60,7 +61,7 @@ const CartCrossSellsProduct = ( {
 						/>
 						<ProductPrice />
 					</div>
-					<ProductButton />
+					<ProductButton noticeContext={ noticeContexts.CART } />
 				</ProductDataContextProvider>
 			</InnerBlockLayoutContextProvider>
 		</div>
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx
index bd323c9eb70..c7ac25d3465 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx
@@ -118,6 +118,7 @@ export const AddToCartButton = ( {
 	className,
 	style,
 	collection,
+	noticeContext,
 }: AddToCartButtonAttributes ): JSX.Element => {
 	const {
 		id,
@@ -128,7 +129,10 @@ export const AddToCartButton = ( {
 		is_in_stock: isInStock,
 	} = product;
 	const { dispatchStoreEvent } = useStoreEvents();
-	const { cartQuantity, addingToCart, addToCart } = useStoreAddToCart( id );
+	const { cartQuantity, addingToCart, addToCart } = useStoreAddToCart(
+		id,
+		noticeContext
+	);
 	const addedToCart = Number.isFinite( cartQuantity ) && cartQuantity > 0;

 	// Check if this is a cart-contents collection
@@ -356,6 +360,7 @@ export const Block = ( props: BlockAttributes ): JSX.Element => {
 								}
 								productEntity={ props.product }
 								collection={ collection }
+								noticeContext={ props.noticeContext }
 							/>
 						) : (
 							<AddToCartButtonPlaceholder
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx
index 62d94907a7a..92a0023792c 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx
@@ -96,6 +96,12 @@ describe( 'AddToCartButton', () => {
 		expect( link ).toHaveAttribute( 'href', '/cart/' );
 		expect( link ).toHaveAttribute( 'rel', 'nofollow' );
 	} );
+
+	it( 'passes the notice context to the add to cart hook', () => {
+		renderButton( { noticeContext: 'wc/cart' } );
+
+		expect( useStoreAddToCart ).toHaveBeenCalledWith( 1, 'wc/cart' );
+	} );
 } );

 describe( 'Product Button spacing', () => {
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/types.ts b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/types.ts
index 372ba28a9dd..e4161c19707 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/types.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/types.ts
@@ -21,6 +21,7 @@ export interface BlockAttributes {
 	product?: ProductEntityResponse | undefined;
 	isAdmin?: boolean | undefined;
 	collection?: string | undefined;
+	noticeContext?: string | undefined;
 }

 export interface AddToCartProductDetails {
@@ -53,4 +54,5 @@ export interface AddToCartButtonAttributes {
 	};
 	textAlign?: ( WithClass & WithStyle ) | undefined;
 	collection?: string | undefined;
+	noticeContext?: string | undefined;
 }