Commit 768c4f607cf for woocommerce

commit 768c4f607cf750e357f3ed1e4c81561ea7832daf
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date:   Wed Sep 30 10:57:39 2026 +0200

    Product status counters: fixed a fatal error during background revison save in the admin when a null value was dispatched instead of a post object. (#69231)

    Relax \Automattic\WooCommerce\Caches\ProductCountCacheService::update_on_product_status_changed post parameter type expectation to account for prod environments.

diff --git a/plugins/woocommerce/changelog/fix-WOOPLUG-7836-product-counters-fatal-during-background-save b/plugins/woocommerce/changelog/fix-WOOPLUG-7836-product-counters-fatal-during-background-save
new file mode 100644
index 00000000000..9b516c3db84
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-WOOPLUG-7836-product-counters-fatal-during-background-save
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fixed a fatal error in persistent product status counters during background revision save in the admin when a null value was dispatched instead of a post object.
diff --git a/plugins/woocommerce/src/Caches/ProductCountCacheService.php b/plugins/woocommerce/src/Caches/ProductCountCacheService.php
index 76ab5927483..3a0f8a9d468 100644
--- a/plugins/woocommerce/src/Caches/ProductCountCacheService.php
+++ b/plugins/woocommerce/src/Caches/ProductCountCacheService.php
@@ -65,7 +65,7 @@ class ProductCountCacheService {

 		// transition_post_status owns all mid-lifecycle status changes; woocommerce_new_product corrects for creation-time
 		// ephemeral transitions before the final status is committed; before_delete_post closes the lifecycle.
-		add_action( 'transition_post_status', array( $this, 'update_on_product_status_changed' ), 10, 3 );
+		add_action( 'transition_post_status', array( $this, 'update_on_product_status_changed_skip_autosave' ), 10, 3 );
 		add_action( 'before_delete_post', array( $this, 'update_on_product_deleted' ), 10, 2 );
 	}

@@ -130,6 +130,21 @@ class ProductCountCacheService {
 		// - However, this scenario is a false positive because it occurs within the same PHP process, where hooks are executed sequentially.
 	}

+	/**
+	 * Update the cache whenever a product status changes.
+	 *
+	 * @param string       $new_status The new post status.
+	 * @param string       $old_status The previous post status.
+	 * @param null|WP_Post $post       The post object (may be null during autosaves/revisions).
+	 *
+	 * @return void
+	 */
+	public function update_on_product_status_changed_skip_autosave( string $new_status, string $old_status, $post ): void {
+		if ( $post instanceof WP_Post ) {
+			$this->update_on_product_status_changed( $new_status, $old_status, $post );
+		}
+	}
+
 	/**
 	 * Update the cache whenever a product status changes.
 	 *