Repository navigation
Keep the cart store correct for custom fields, mixed bodies and variant swaps - #4133
Open
mdamjanic7 wants to merge 4 commits into
Open
mdamjanic7 wants to merge 4 commits into
mdamjanic7 wants to merge 4 commits into
Conversation
Contributor
|
Oxygen deployed a preview of your
Learn more about Hydrogen's GitHub integration. |
The cart server handlers return the app's full CartFragment on every mutation, but the store copied only id, checkoutUrl, updatedAt, totalQuantity and cost from the response. Custom fields stayed stale after a change and were missing on a cart created by the first add. The store now takes every non-line field from the latest settled response, under the existing ordering and revalidation guards.
parseJsonBody picked the first of note, discountCodes, attributes and lines and ignored the rest. Standard Actions accepts all of them in one updateCart call and dispatches one event per kind, so the store projected every change while the server applied only one. A body with more than one of these fields is now an invalid_cart_request, so every projection rolls back and the caller sees the error.
mdamjanic7
force-pushed
the
preview-fix/4a-cart-route-and-fragment
branch
from
October 1, 2026 22:51
ea2094f to
04017f4
Compare
mdamjanic7
marked this pull request as ready for review
October 1, 2026 23:03
mdamjanic7
force-pushed
the
preview-fix/4a-cart-route-and-fragment
branch
from
October 1, 2026 23:54
04017f4 to
3eea9d9
Compare
partitionLines classified a JSON line with both id and merchandiseId as an update but copied only quantity, attributes and sellingPlanId, so a variant swap through the cart route changed only the quantity. Updates now carry merchandiseId to cartLinesUpdate, and CartLineUpdateInput declares it. Shopify can return the swapped line under a new line ID. The store only matched the submitted ID, so the line disappeared. When no other work overlaps the change, the store now takes the lines from the response. Otherwise it keeps the line until the revalidation that overlapping work already triggers, so a failed refresh doesn't lose it. A missing line only means removal when the change was a removal.
…ons prerequisite The cart UI skill covered forms and refresh() only, so code that changes the cart without a form (gift rules, sweeps, attribute writers) had no guidance and tended to hand-roll fetch calls. Document the Standard Actions runtime prerequisite and how to use Shopify.actions.updateCart with the store.
mdamjanic7
force-pushed
the
preview-fix/4a-cart-route-and-fragment
branch
from
October 2, 2026 00:08
3eea9d9 to
6f7db3d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WHY are these changes introduced?
Apps that change the cart from code (
Shopify.actions.updateCart) hit three silent gaps:CartFragmentfields go stale. The store only copies id, checkout URL, totals and cost from mutation responses, so fields likeappliedGiftCardsstay outdated after a change.linesandattributesruns one mutation and silently drops the other.merchandiseIdon line updates. Once it's forwarded, Shopify can return the swapped line under a new ID, and the store loses it.The cart skill also has no guidance for code-driven changes, so apps call the cart route directly and bypass the store.
WHAT is this pull request doing?
400 invalid_cart_request, and the store rolls back.merchandiseId. If the response no longer contains the submitted line ID, the store takes the lines from the response, or, when other changes overlap, keeps the line until the refresh they trigger.hydrogen-cart-uidocuments code-driven changes: the Standard Actions prerequisite, when the store is ready, one kind of change per call, and one line per update, removal or swap (additions can batch).Trade-offs / behavior changes
quantitystays required on line updates (Standard Actions requires it, and the store projects from it).HOW to test your changes?
pnpm --filter @shopify/hydrogen test. It covers custom fields across mutations, mixed-body rejection, and variant swaps returned under the same or a new line ID.