Known Issues & Gotchas
Verified bugs, edge cases, and anti-patterns in the Checkout module with proven workarounds.
Verified bugs, edge cases, and anti-patterns in the Checkout module with proven workarounds.
Severity Guide: Critical = Data loss/security risk | Major = Significant UX/functionality impact | Minor = Edge cases, cosmetic issues
When multiple AJAX requests are made simultaneously during checkout (e.g., address validation + shipping estimate), PHP session locking can cause race conditions where the quote state becomes inconsistent.
2.3.x - 2.4.x (partially addressed in 2.4.6)
Direct REST API calls to payment-information endpoint can bypass frontend address validation, allowing orders with incomplete or invalid addresses to be placed.
/V1/carts/mine/payment-information
If the "Place Order" button is clicked multiple times before the response returns (slow network), multiple orders can be created. The default frontend disables the button but can be bypassed.
No server-side idempotency check
After changing the shipping address, available shipping methods may not refresh until the page is reloaded. This is particularly common with custom shipping carriers or when country/region changes.
Force shipping rates refresh by triggering Magento_Checkout/js/action/select-shipping-address
action with the updated address, or clear the shipping rates cache in customer-data.
Guest checkout email validation differs between frontend and API. Some invalid email formats pass API validation but fail frontend validation, causing confusion.
Add consistent email validation on both frontend (Knockout validator) and backend (plugin on GuestPaymentInformationManagement). Use PHP's filter_var with FILTER_VALIDATE_EMAIL.
If a customer goes back from payment to shipping step and returns, the terms and conditions checkbox state may be lost, requiring re-acceptance.
Store agreement acceptance state in localStorage or quote extension attributes.
Use a mixin on Magento_CheckoutAgreements/js/view/checkout-agreements.
When applying a coupon code in checkout, the sidebar totals may not update until the customer interacts with another element or refreshes the page.
After coupon apply, trigger quote.totals() observable update
and invalidate the checkout-data customer-data section.
The checkout step progress indicator (shipping → payment) lacks proper ARIA attributes for screen reader users.
Add role="progressbar", aria-valuenow,
and aria-valuetext attributes to the step indicator template.
If an AJAX request fails during checkout, the loading spinner may remain visible instead of being dismissed, leaving the checkout appearing frozen.
Ensure error handlers call fullScreenLoader.stopLoader()
in all code paths. Add global AJAX error handler to dismiss loader.