Commit 97ca2695a80 for woocommerce

commit 97ca2695a80279dd9b7f09fa4876d32a641a2fb0
Author: Luis Felipe Zaguini <26530524+zaguiini@users.noreply.github.com>
Date:   Wed Nov 4 12:33:18 2026 -0300

    Return the saved-order error from order-update when a field fails (#70605)

    * Return the saved-order error from order-update when a field fails

    prepare_response() nested a field error under the order key, so
    execute_change() did not see it and the client got no saved flag or
    order ID. A retry then applied the same change again.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    * Cover line item fields in the order-update saved-order test

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    ---------

    Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

diff --git a/plugins/woocommerce/changelog/wooairr-695-order-update-saved-error b/plugins/woocommerce/changelog/wooairr-695-order-update-saved-error
new file mode 100644
index 00000000000..35b7cfa3471
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooairr-695-order-update-saved-error
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+Comment: Fix the saved-order error of the order-update ability.
+
diff --git a/plugins/woocommerce/src/Internal/Abilities/Domain/OrderUpdate.php b/plugins/woocommerce/src/Internal/Abilities/Domain/OrderUpdate.php
index c8e4db293aa..5b725172c07 100644
--- a/plugins/woocommerce/src/Internal/Abilities/Domain/OrderUpdate.php
+++ b/plugins/woocommerce/src/Internal/Abilities/Domain/OrderUpdate.php
@@ -250,12 +250,15 @@ class OrderUpdate extends ActionableAbility {
 	 * client gets the IDs of the lines it added.
 	 *
 	 * @param \WC_Order $subject Saved order.
-	 * @return array
+	 * @return array|\WP_Error
 	 */
-	public function prepare_response( $subject ): array {
-		return array(
-			'order' => self::format_order_for_response( $subject, true ),
-		);
+	public function prepare_response( $subject ) {
+		$order = self::format_order_for_response( $subject, true );
+		if ( is_wp_error( $order ) ) {
+			return $order;
+		}
+
+		return array( 'order' => $order );
 	}

 	/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php b/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php
index ed6441e5b0c..00605cdf098 100644
--- a/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php
@@ -1958,6 +1958,33 @@ class ExtensibleAbilitiesTest extends \WC_REST_Unit_Test_Case {
 		$this->assertSame( 'completed', wc_get_order( $order->get_id() )->get_status() );
 	}

+	/**
+	 * @testdox Should name the saved order in the error when order-update saves and an order or line item field value then fails its schema.
+	 * @dataProvider invalid_order_field_values
+	 *
+	 * @param string $resource_name Resource.
+	 * @param array  $schema        Field schema.
+	 * @param mixed  $value         Value that the get_callback returns.
+	 */
+	public function test_an_order_update_that_saves_before_a_field_fails_names_the_saved_order( string $resource_name, array $schema, $value ): void {
+		$this->setExpectedIncorrectUsage( ExtensibleAbilities::class . '::register_field' );
+		$this->register_invalid_field( $resource_name, $schema, $value );
+		$order = \WC_Helper_Order::create_order();
+
+		$result = wp_get_ability( 'woocommerce/order-update' )->execute(
+			array(
+				'id'            => $order->get_id(),
+				'customer_note' => 'Probe',
+			)
+		);
+
+		$this->assert_field_output_invalid( $result, $resource_name );
+		$this->assertStringContainsString( 'The change is saved on the order ' . $order->get_id() . ',', $result->get_error_message() );
+		$this->assertTrue( $result->get_error_data()['saved'] );
+		$this->assertSame( $order->get_id(), $result->get_error_data()['id'] );
+		$this->assertSame( 'Probe', wc_get_order( $order->get_id() )->get_customer_note() );
+	}
+
 	/**
 	 * @testdox Should fail orders-query with a named error that keeps the exception text out when a get_callback throws.
 	 */