POS UI Extensions (POS 11.11.x): cart writes resolve successfully but are not persisted — in some cases after the returned cart confirms them

POS UI Extensions (POS 11.11.x): cart writes resolve successfully but are not persisted — in some cases after the returned cart confirms them


We build a fee-management app whose POS smart-grid tile writes fee lines (e.g. government-regulated bottle deposits) into the cart via the POS UI Extensions Cart API. On one merchant’s devices we are observing cart writes that the API reports as successful — in some cases confirmed by the cart object bulkCartUpdate itself returns — that are not present on the completed order. We have spent several release cycles eliminating app-side causes and instrumenting the extension in detail, and the remaining failures appear to occur inside POS after it has accepted the write. We’d like to know whether other developers are observing this, and whether Shopify can confirm whether there is a known issue with device-local cart state diverging from what checkout captures.

Environment

  • Shopify POS (iOS) 11.11.1, two physical retail locations, multiple devices
  • POS UI Extensions, api_version = "2026-07", target pos.home.tile.render
  • Cart writes via api.cart.bulkCartUpdate, api.cart.addCustomSale, api.cart.removeLineItem; cart state observed via the cart subscribable and api.cart.get
  • Every write is confirmed against the cart subscription before we treat it as done, with confirmation budgets of 3.5–4 s (above this platform’s measured cart-projection latency of 2–3.5 s), bounded retries, and post-apply verification

The four failure shapes we can document

All of these are from our production telemetry (App Events), Aug 14–18, 2026, cross-checked against completed orders. For clarity on attribution: the only POS-generated error message involved is Failed to find new custom sale line item (thrown by addCustomSale); every other quoted string below is a label from our own instrumentation, included in case it helps correlate. Shapes 2–4 involve no error from the API at all — the calls resolve successfully.

  1. Dropped adds. addCustomSale rejects with the POS-thrown error Failed to find new custom sale line item, and for the following 3.5 s no matching line of any kind appears in the cart subscription — the line was never created. (We are aware this error is nominally a locate failure that can fire after a line was created, or when an identical line already exists; our recovery poll checks for both a newly created line and any existing matching fee line before treating it as a failed add. In these cases the poll finds neither.)

  2. Dropped removes. removeLineItem resolves successfully — no error is surfaced by the API — and the line is still present in the cart 3.5 s later. Our instrumentation labels these Stale fee line <uuid> was not removed before replacement.

  3. Dropped bulk writes. bulkCartUpdate resolves successfully — again, no error surfaced — and the written fee line appears neither in the returned cart nor in 4 s of polling the live cart (observed confirm_waited_ms 4,124–4,149, i.e. the full budget). We re-issue the identical idempotent payload once; the second write behaves the same way. Our instrumentation labels these bulkCartUpdate resolved without applying: <fee title>@<price>x<qty>.

  4. Confirmed-then-vanished writes. In documented cases the apply succeeded by every signal the API exposes — including one where the cart object returned by bulkCartUpdate contained the fee line (the first attempt’s returned cart did not, so the returned cart is not simply echoing our input) — and the completed order has no fee line. As far as we can tell, there is no API through which an extension can observe this happening: the returned cart, the cart subscription, and a post-apply cart.get all read the same device-local state, and that state is what diverges from the order.

A recurring episode signature

The shapes above co-occur in a repeating sequence we have now captured multiple times per day. A representative episode (timestamps relative, from one POS session on 2026-08-18):

T+0.0s    bulkCartUpdate #1 resolves; fee line absent from the returned cart and
          from 4.1 s of polling the live cart. The identical idempotent payload
          is re-issued (#2); also absent.
T+2.1s    Sequential fallback: addCustomSale rejects with the POS error
          "Failed to find new custom sale line item".
T+2.1–5.6s  A 3.5 s poll of the cart subscription finds no newly created line
          AND no existing fee line of any kind.
T+~12s    Next retry: bulkCartUpdate #3 resolves (+ idempotent re-issue #4);
          fee line absent again, full 4.1 s confirmation budget expires.
T+~16s    Sequential apply succeeds; the fee line is present in the device-local
          cart and passes post-apply verification.
Result    The completed order (merchant-audited) contains no fee line.

Within one ~20-second episode: four consecutive bulkCartUpdate calls resolved without their write persisting, one addCustomSale threw the locate error with nothing appearing in the cart, and the eventual successful, verified apply still did not reach the order.

One point we want to flag because it rules out a matching bug on our side: the episode contains three independent observation channels — the cart returned by bulkCartUpdate, 4 s of polling the cart subscription after the bulk write, and a separate 3.5 s poll triggered seconds later by POS’s own locate error on the sequential path — and all three agree the fee line was not in the cart. If our post-write matching were producing false negatives (e.g. price or property format differences), the third channel would have found and adopted the supposedly-applied line; it never does.

The merchant-facing outcomes map onto the shapes consistently: orders missing the fee entirely correspond to the episode signature above, and orders with the fee at a stale amount correspond to repeated shape-2 events (the remove resolves, the line persists, and our extension declines to add a replacement on top of a line it cannot confirm removed, to avoid a double charge — so the fee stays at its previous quantity).

Two timing observations that point toward state-sync loss rather than network slowness: cart operations resolve promptly throughout (no hangs or timeouts in the affected windows), and our bulk-confirmation timing distribution is bimodal — writes confirm either immediately or not within the 4 s budget, essentially never in between. Writes appear to be discarded whole rather than delayed.

What we have ruled out on the app side

  • We shipped a hardening release that closed every app-side failure cause we have identified (confirmation budgets sized to measured platform latency, idempotent re-issue of unconfirmed bulk writes, adoption of already-present lines instead of duplicate adds, price/quantity comparison tolerant of number-vs-string and formatting differences in returned line shapes, ownership guards). Telemetry from these devices shows each of those mechanisms operating as designed; the shapes above are what remains.
  • A different delivery mechanism produced the same failure rate: we trialed our Shopify Functions–based method (which writes line-item properties instead of custom-sale lines) on the same store for two days. It failed at the same rate, including orders where the property writes were dropped in the same way.

On audited days, roughly 16–32% of fee-eligible POS orders completed with the fee missing or at a stale amount, across both locations. The fees in question are regulated deposits, so each occurrence is an undercharge.

One environmental data point we have not been able to confirm or rule out: the affected terminals at one location run hard-wired through the POS hub with WiFi as a redundant fallback. We currently have no API-visible signal that would let us correlate failures with network path.

Questions

  1. Is there a known issue on POS 11.11.x with device-local cart state diverging from what checkout/order capture records — i.e., a write the device has accepted (and returns in the bulkCartUpdate cart) not being present on the created order?
  2. Is the cart returned by bulkCartUpdate intended to be authoritative? Under what conditions can a write it reflects subsequently be discarded?
  3. Under what conditions does addCustomSale throw Failed to find new custom sale line item with no line being created at all? We understand it as a locate failure that can follow a successful create, but we consistently observe it with nothing appearing in the cart subscription afterwards.
  4. Is a wired-hub + WiFi-fallback network configuration a known factor in cart state sync? Is there a recommended configuration for multi-path setups?
  5. Is there (or could there be) a way for an extension to observe server-side cart state vs. device-local state, or an event fired when POS rebuilds/reconciles a cart?
  6. Are other developers seeing addCustomSale / bulkCartUpdate / removeLineItem calls that resolve successfully with no resulting cart change on 11.11.x?

We have a detailed evidence package — session IDs, event timelines with millisecond timings, and order numbers correlated to sessions — and can share it with Shopify staff on request.

For completeness: we’re aware of, and are not conflating this with, the separately confirmed platform issue where bulkCartUpdate ignores attributedUserId (Shopify-confirmed July 2026), and the 11.11 issue where the cart emitted TaxLine.rate as a string where the input schema documents a number — we sanitize for the latter. The failures above persist with both handled.

Any corroboration from other developers, or guidance from Shopify, would be much appreciated. Thank you!