Shopify POS UI Extension Cart Mutations: Fix Rejected Writes
Shopify POS UI extensions now reject unconfirmed cart mutations. Learn why unconfirmed writes fail, how to confirm cart writes, and how to fix your extension.

Shopify POS UI extensions now reject cart mutations that are not confirmed by the POS runtime, so any extension that writes to the cart without waiting for confirmation will fail. If your POS extension stopped adding, updating, or removing line items after a recent release, the cause is almost always an unconfirmed write — a mutation fired before the cart state was verified. This guide explains what changed, how to spot the failure, and how to restructure your Shopify POS UI extension cart mutations so they pass validation every time.
The change affects both public apps and private extensions built for a single merchant. It does not matter whether you use the latest POS UI extension APIs or a custom bridge; if the write is not confirmed, the cart rejects it. The fix is predictable once you understand the sequence Shopify expects.
What changed in Shopify POS UI extension cart mutations
Shopify tightened the contract between POS UI extensions and the cart. A cart mutation is now treated as a request that must be confirmed by the runtime before it is applied. Previously, many extensions could fire a mutation and assume success. That assumption no longer holds.
In practice, the runtime validates the current cart state, checks that the mutation is permitted for the extension's scopes and context, and only then applies it. If the extension sends a write that cannot be tied to a confirmed state, the mutation is rejected rather than silently queued.
This is part of a broader move toward deterministic cart behavior on POS. The same principle already applies to many Shopify APIs: the platform prefers explicit, verifiable operations over fire-and-forget writes. POS is now consistent with that model.
The difference between a request and a confirmed write
A request is what your extension sends. A confirmed write is what the runtime acknowledges and applies. The gap between them is where unconfirmed writes live. If your code treats the request as the result, you are relying on an unconfirmed write.
Why unconfirmed writes are now rejected
Unconfirmed writes create three problems Shopify is no longer willing to absorb:
- Race conditions. Two extensions or a staff member and an extension can mutate the same cart at once. Without confirmation, the last write wins and the cart can end up in an impossible state.
- Inventory and pricing drift. A line item added without confirmation may not match the current price, tax, or stock level. On POS, that means a customer is charged the wrong amount or a sale is recorded against unavailable stock.
- Auditability. Confirmed writes produce a clear record of what changed and when. Unconfirmed writes do not, which makes disputes and reconciliation harder.
Rejecting unconfirmed writes forces extensions to read the current state, confirm it, and only then mutate. That is slower to write but far more reliable in production.
Symptoms you will see
Most teams notice the problem in one of four ways:
- Silent failures. The mutation call returns without an error, but the cart does not change.
- Explicit error responses. The runtime returns a rejection with a reason such as an invalid or unconfirmed cart state.
- Partial application. One line item updates and another does not, leaving the cart inconsistent.
- Intermittent behavior. The extension works in a test store with an empty cart and fails in a busy store with concurrent activity.
If you see any of these, stop adding retries. Retrying an unconfirmed write usually produces more rejections, not fewer.

How to confirm cart writes before mutating
The fix is a sequence, not a single API call. Apply it to every cart operation in your extension.
1. Read the current cart state
Fetch the cart before you change it. You need the current line items, quantities, and any cart-level attributes your mutation depends on. Do not cache this across user actions; POS carts change quickly.
2. Validate your intended change against that state
Check that the line item exists, that the quantity you are setting is valid, and that the mutation is allowed in the current context. If the cart changed since your last read, re-read rather than forcing the write.
3. Send the mutation and await confirmation
Send the mutation and wait for the runtime to confirm it. Treat the confirmation as the source of truth, not the request. If confirmation does not arrive, do not assume success.
4. Handle rejection explicitly
On rejection, re-read the cart, recompute the change, and try once more. If it fails again, surface a clear message to the staff member instead of looping.
5. Log the confirmed result
Record what was actually applied. This makes support and reconciliation far easier when a merchant reports a discrepancy.
A quick checklist
| Step | Do | Do not |
|---|---|---|
| Read | Fetch cart state immediately before the write | Reuse a stale cart snapshot |
| Validate | Check item, quantity, and context | Assume the item still exists |
| Mutate | Send and await confirmation | Treat the request as success |
| Reject | Re-read, recompute, retry once | Retry blindly in a loop |
| Log | Store the confirmed result | Log only the request |
Testing your POS extension after the change
Testing on an empty cart hides the bug. Use a test store with realistic data and concurrent activity.
- Test with a populated cart. Add several line items, then run your mutation.
- Test concurrent edits. Change the cart from the POS UI while your extension writes, and confirm your extension recovers.
- Test rejection paths. Force a rejection and verify your extension re-reads and retries once, then shows a clear message.
- Test on the devices you support. POS behavior can differ between tablet and mobile form factors.
- Test after each POS release. This contract is enforced by the runtime, so re-run your suite when POS updates.
If your extension is a custom private app, add these cases to your release checklist. If it is a public app, treat them as regression tests before every submission.
Getting help with custom Shopify POS extensions
If your extension is failing in production and you need it fixed quickly, the fastest path is usually a focused audit of every cart write, followed by a migration to the confirmed-write sequence above. That is exactly the kind of work we do: custom Shopify apps, private extensions, and POS integrations built to survive platform changes. You can see how we approach this on our Shopify apps page, or compare our product options on the products page.
If you would rather not maintain the extension yourself, we also take over existing POS extensions, fix the cart mutation paths, and keep them current as Shopify ships updates. The goal is simple: your staff keep selling, and your extension stops rejecting writes.
Related reading
Frequently asked questions
Why did my Shopify POS UI extension stop adding items to the cart?
Your extension is most likely sending an unconfirmed cart mutation. The POS runtime now rejects writes that are not confirmed against the current cart state. Read the cart, validate the change, send the mutation, and wait for confirmation before treating it as applied.
What is an unconfirmed write in a Shopify POS UI extension?
An unconfirmed write is a cart mutation your extension sends without waiting for the runtime to acknowledge and apply it. Your code treats the request as the result. Because the runtime no longer applies these writes, the cart does not change even though no error is thrown.
Does this affect private POS extensions as well as public apps?
Yes. The change is enforced by the POS runtime, so it applies to public apps and to private extensions built for a single merchant. If the write is not confirmed, it is rejected.
Should I add retries to fix rejected cart mutations?
Not on their own. Retrying an unconfirmed write usually produces more rejections. The correct fix is to read the current cart state, validate your intended change, send the mutation, await confirmation, and only retry once after re-reading the cart.
How do I test a POS extension for this behavior?
Test with a populated cart, not an empty one. Simulate concurrent edits from the POS UI while your extension writes, force rejection paths, and verify your extension re-reads and retries once before showing a clear message. Re-run the suite after each POS release.
Can you fix an existing Shopify POS extension that is failing?
Yes. We audit every cart write in the extension, migrate it to the confirmed-write sequence, and take over maintenance so it stays compatible as Shopify updates POS. Contact us with a short description of the failure and we will reply as soon as possible.
Fix your POS extension cart mutations
Tell us what your POS extension does and where it fails. We will audit the cart write paths, migrate them to confirmed writes, and keep the extension current as Shopify ships updates.