Shopify.cart.current.value Returns Stale Data After Order Completion

Summary

After completing an order in Shopify POS, shopify.cart.current.value.lineItems does not seem to be cleared/reset properly. When a POS UI Extension subsequently reads this value and uses it in a bulkCartUpdate call, the stale line items from the previous order are re-added to the cart.

This issue may be related to Cart properties in Shopify POS UI Extension are one state behind (stale data)

Environment

  • Platform: Shopify POS (iOS)

  • POS App Version: Latest (10.19.1)

  • Extension API Version: 2025-10

  • Extension Type: POS UI Extension (pos.home.tile.render, pos.home.modal.render)

  • Affected API: shopify.cart (Cart API)

Steps to Reproduce

  1. Open Shopify POS app with a POS UI Extension installed that uses bulkCartUpdate

  2. Add items to cart (with or without custom line item properties)

  3. Complete checkout and process payment successfully

  4. Order should now be complete and cart should be empty

  5. Add a new item to cart via the extension using bulkCartUpdate

  6. Observe: Items from the previous order reappear in the cart

Expected Behavior

After order completion:

  • shopify.cart.current.value should return an empty cart or a cart with lineItems: []

  • Subsequent bulkCartUpdate calls should only contain the new items being added

Actual Behavior

After order completion:

  • shopify.cart.current.value.lineItems still contains items from the previous completed order

  • When extension calls bulkCartUpdate with [...shopify.cart.current.value.lineItems, newItem], the old items are re-added to the cart

Some of our merchants have sent through screen recordings of this issue - please see below:

Technical Analysis

Our extension uses bulkCartUpdate to atomically add items with properties in a single API call:

// This is the recommended pattern for atomic cart operations
const freshCart = shopify.cart.current.value;

const newLineItem = {
  uuid: generateUUID(),
  variantId: selectedVariantId,
  quantity: 1,
  properties: lineProperties,
  // ... other required fields
};

// Spread existing items + add new item
const updatedLineItems = [
  ...(freshCart?.lineItems || []),  // ⚠️ BUG: Contains stale items after order completion
  newLineItem,
];

await shopify.cart.bulkCartUpdate({
  lineItems: updatedLineItems,
  properties: mergedCartProperties,
  cartDiscounts: freshCart?.cartDiscounts || [],
});

The bug: After order completion, freshCart.lineItems is not empty - it still contains the line items from the completed order. When we spread these into the new updatedLineItems array, the old items are re-added to the cart.

Evidence from Debug Logs

We added debug logging to track the cart state:

debugLog("[handleAddToCart] Fresh cart state:", {
  lineItemsCount: freshCart?.lineItems?.length || 0,
  lineItems: freshCart?.lineItems?.map((li) => ({
    uuid: li.uuid,
    variantId: li.variantId,
    quantity: li.quantity,
  })),
});

After order completion, before adding new item:

lineItemsCount: 3  // Should be 0!
lineItems: [
  { uuid: "abc-123", variantId: 12345, quantity: 1 },  // From previous order
  { uuid: "def-456", variantId: 67890, quantity: 2 },  // From previous order
  { uuid: "ghi-789", variantId: 11111, quantity: 1 },  // From previous order
]

User Reports

We have received multiple reports from merchants describing this exact behavior:

  1. “After checkout and after we complete a sale, the items from that sale get added back to the cart”

  2. “Orders from the previous transaction are appearing in the next transaction… This is a critical issue, as in some locations multiple SKUs are being carried over, resulting in customers being overcharged.”

  3. “We have also had items from previous orders loading into the current cart”

Workaround Implemented

We have reverted to using the legacy sequential API calls which do not read the existing cart state:

// Legacy approach - does NOT read existing lineItems
await shopify.cart.addLineItem(variantId, quantity);
await shopify.cart.addLineItemProperties(uuid, properties);
await shopify.cart.addCartProperties(cartProperties);

This workaround avoids the bug because addLineItem appends to the cart rather than replacing it, so stale data in shopify.cart.current.value is never spread into the update.

Impact

  • Severity: Critical - affects every transaction following the first

  • User Impact:

    • Customers being overcharged for items they didn’t order
    • Staff confusion and manual workaround required
    • Risk of processing incorrect orders
    • Loss of merchant trust
  • Workaround Available: Yes - use sequential addLineItem calls instead of bulkCartUpdate

  • Workaround Trade-offs: Slower performance, multiple Cart Transform executions, potential race conditions

Questions for Shopify Team

  1. Is shopify.cart.current.value supposed to be cleared after order completion?

  2. Is there a cart subscription event we should be listening to for cart reset?

  3. Was there a recent change to cart state management in the POS app?

  4. Is there an alternative API to get a guaranteed-fresh cart state?

Suggested Fix

The shopify.cart.current.value observable should be reset to an empty cart state (or new cart) after order completion, before the next transaction begins.

Additional Notes

  • The issue does not occur when using addLineItem (which doesn’t read existing cart state)

  • The issue only occurs when using bulkCartUpdate with spread of existing lineItems

  • This suggests the bug is specifically in the cart state management, not in the bulkCartUpdate API itself

  • The subscription to shopify.cart.current also does not fire a “cart cleared” event after order completion

Thank you so much for your help :folded_hands:t5: