Title: applyCartLinesChange succeeds but cart doesn’t update reliably when shipping country changes — possible conflict with auto-focus on checkout fields
Body:
Hi Shopify Devs,
I’ve built a Checkout UI Extension that dynamically adds/removes deposit products based on the shipping country selected during checkout. Here’s a quick rundown of what the extension does:
Listens for shippingAddress changes via useShippingAddress().
On a valid countryCode change, runs logic to:
Remove deposit-related products not needed for that region.
Add region-specific deposit products using applyCartLinesChange.
The behavior was rock-solid during development. Even now its completely intact But recently — and only intermittently — when I change the shipping country using the country dropdown, Shopify auto-focuses the Postal Code or City field, and that somehow disrupts my extension’s cart modification logic.
Again, this only happens when Zip Code field gets auto focused, Like in 2 out of 10 attempts which proves my logic was and still is okay unless the Auto-Focus on Zipe code field happens when shipping country changed.
Symptoms:
applyCartLinesChange() resolves successfully (verified in logs and DevTools network tab with success response).
But the cart does not reflect the changes (no line added/removed).
This only happens sometimes, and strangely, adding a delay using setTimeout (400–500ms) reduces but does not eliminate the issue. In this case the Auto-focus on Zip code maybe gets suppressed on most attempts but this isn’t a sufficient solution.
There are no errors from the extension code or hook invocations.
What I’ve Tried:
Verified applyCartLinesChange response is { status: "success" }.
Verified network tab on the operations and the response is status = 200 when the Auto focus thing happen.
Theories:
The auto-focus on postal code/city input might trigger a checkout re-render that wipes/overrides the cart state shortly after my updates.
Some internal debounce or batching of Shopify’s shipping updates might conflict with cart updates fired too soon.
Questions:
Is this auto-focus behavior intentional or recently introduced?
Is there a recommended pattern to queue or delay cart modifications safely after country updates?
Are there lifecycle hooks or callbacks we can rely on to detect when the Shopify checkout has “settled” post-country-change?
Can applyCartLinesChange() be “cancelled” silently if another re-render or input focus event happens soon after?
Any advice, patterns, or insights from the team or community would be incredibly helpful!
Thanks in advance!
Hey @work4inventions thanks for reaching out. This is the first report of this behaviour I’ve seen on my end, and does definitely seem odd. I’m wondering if it potentially has to do with race conditions on our side where one change takes precedent over the other (I have seen issues like this pop up before in Checkout UI extensions, specifically with Cart Lines.). Adding the delay does point to this being a potential reason for that happening, especially since the applyCartLinesChange call does return a successful response.
Would you be able to share an example of a full applyCartLinesChange action request/response if possible (as well as the shop ID for the affected merchant)? If you have timestamps for an example of this happening that would be super helpful as well, we can check logs on our end to narrow down if something is happening on our side of things. Also helpful would be the X-Request-ID header from the network request if you’re able to share that!
Hey @Alan_G, Thanks for the clarification. Here’s a real instance where applyCartLinesChange returned a success response, but no changes were reflected in the checkout UI. This issue occurs only when the country dropdown is changed and the checkout auto-focuses on the postal code or city field.
This runs inside a setTimeout after detecting a shippingAddress.countryCode change as I mentioned that setTimeout with 500ms resolved partially but suppressed Shopify’s auto focus behaviour:
We added the timeout to mitigate this issue, and it works most of the time. But when autofocus kicks in immediately after the country change, the cart updates still sometimes fail to render in the UI despite success responses.
Hey @work4inventions, sincere apologies for the delay in getting back to you. Thanks you for your patience on this and the details you shared.
I think my next step here is to get in touch with our product team to see if this is a possible issue on our end, but there’s one last check/confirmation that would be incredibly helpful.
Just want to clarify, when the UI doesn’t update after a successful applyCartLinesChange call, could you verify if useCartLines() actually shows the correct updated cart state or if you can check to see if the cart itself is updated in the storefront cart page if possible? This would help us determine if it’s purely a UI rendering issue versus the cart state itself not updating properly.
Once I have this final piece, I think I’ll have everything needed to get this properly investigated by our Checkout UI team.
Thanks again for bearing with me on this, I really appreciate you pinging me in the thread here again, we’ll get this looked at.
Hey @Alan_G , I verified state sourced from useCartLines() does not get updated.
Here is how I checked it out,
Directly after applyCartLinesChange call.
500ms delay after applyCartLinesChange call.
Log the state on checkout load to check fresh state of useCartLines() , By refreshing after the operations (non-updated UI case). It doesn’t contain the added lines.
And another thing I observed is something into the logs which might be related to this issue. (Though, didn’t go deep into this to know the root of occurrences but I assume it’s when there is a setTimeOut which suppresses auto-focus on shipping country change )
Hey @work4inventions, thanks for confirming that useCartLines() doesn’t reflect the updated state - this does seem to be a cart state issue, not just UI rendering.
The auto-focus behavior and applyCartLinesChange failing silently despite success responses is definitely a bit concerning.
If you have any additional Request IDs and timestamps from other occurrences beyond the three you’ve already shared (you should be able to find the request IDs in the API response headers for those actions in Chrome Dev tools), those would be helpful. Also, if you’re able to, capture the full error logs around that “Cannot set properties of null” error (no worries if not), that would give us more context. As well, if possible, a screen recording showing the exact replication steps and the auto-focus behavior when it fails would be incredibly valuable for our team to understand the issue so we can replicate things on our end here.
Once I have this, my next step will be reaching out to the relevant product team on our end with all the details.
In the meantime, I’d definitely say to continue with your 500ms setTimeout workaround. You might also want to consider adding a verification check after applyCartLinesChange to retry if useCartLines() doesn’t update within a reasonable timeframe at your code-level for the time being.
Hope to hear from you soon so we can get this properly looked at!