Commit da684075add for woocommerce

commit da684075add6f38dd94c9bf897bd2d16bf05568e
Author: Oleksandr Aratovskyi <79862886+oaratovskyi@users.noreply.github.com>
Date:   Wed Sep 30 15:31:01 2026 +0300

    Fix Product Categories List warnings when categories have no visible products (#69181)

    * Fix missing parents in product category trees

    * Add changelog entry for product category tree fix

    * Add regression coverage for empty product category tree

    * Narrow product category tree fix to the empty-root guard

    Child categories whose parent is dropped for a stale count are skipped
    again instead of promoted to the top level. Stale counts after
    reparenting are tracked in #25491.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

    ---------

    Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

diff --git a/plugins/woocommerce/changelog/fix-product-categories-missing-parent-tree b/plugins/woocommerce/changelog/fix-product-categories-missing-parent-tree
new file mode 100644
index 00000000000..f1419a06e26
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-product-categories-missing-parent-tree
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix PHP warnings in the Product Categories List block when listed categories only have hidden or out-of-stock products.
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductCategories.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductCategories.php
index b2c3e6faed0..cf437e5440b 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductCategories.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductCategories.php
@@ -200,7 +200,7 @@ class ProductCategories extends AbstractDynamicBlock {
 		}

 		$parent_id = $children_only ? get_queried_object_id() : 0;
-		$tree      = $categories_by_parent[ 'cat-' . $parent_id ]; // these are top level categories. So all parents.
+		$tree      = $categories_by_parent[ 'cat-' . $parent_id ] ?? []; // these are top level categories. So all parents.
 		unset( $categories_by_parent[ 'cat-' . $parent_id ] );

 		foreach ( $tree as $category ) {
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCategoriesTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCategoriesTest.php
index e6d379a92b4..5c385a1ebcc 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCategoriesTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCategoriesTest.php
@@ -128,4 +128,30 @@ class ProductCategoriesTest extends WC_Unit_Test_Case {
 		$this->assertStringNotContainsString( '>Empty<', $this->render_product_categories() );
 		$this->assertStringContainsString( '>Empty<', $this->render_product_categories( '{"hasEmpty":true}' ) );
 	}
+
+	/**
+	 * @testdox Should render nothing, without warnings, when the current category's children have no visible products.
+	 * @testWith ["hidden", "instock", "no"]
+	 *           ["visible", "outofstock", "yes"]
+	 *
+	 * @param string $catalog_visibility Catalog visibility of the only product.
+	 * @param string $stock_status       Stock status of the only product.
+	 * @param string $hide_out_of_stock  Value of the woocommerce_hide_out_of_stock_items option.
+	 */
+	public function test_children_only_without_visible_products( string $catalog_visibility, string $stock_status, string $hide_out_of_stock ): void {
+		update_option( 'woocommerce_hide_out_of_stock_items', $hide_out_of_stock );
+		$accessories_id = (int) wp_insert_term( 'Accessories', 'product_cat' )['term_id'];
+		$scarves_id     = (int) wp_insert_term( 'Scarves', 'product_cat', array( 'parent' => $accessories_id ) )['term_id'];
+		WC_Helper_Product::create_simple_product(
+			true,
+			array(
+				'category_ids'       => array( $scarves_id ),
+				'catalog_visibility' => $catalog_visibility,
+				'stock_status'       => $stock_status,
+			)
+		);
+		$this->go_to( get_term_link( $accessories_id, 'product_cat' ) );
+
+		$this->assertSame( '', $this->render_product_categories( '{"showChildrenOnly":true}' ) );
+	}
 }