Decoding Magento 2 GraphQL Errors: When Localization Breaks Error Codes
Decoding Magento 2 GraphQL Errors: When Localization Breaks Error Codes
For Magento 2 stores leveraging headless architectures like PWA Studio or custom GraphQL clients, reliable error handling is paramount. However, a recent GitHub issue (#40797) has brought to light a significant challenge: the addProductsToCart GraphQL mutation can return incorrect, often UNDEFINED, error codes when the storefront operates in a non-English locale.
The Localization Conundrum: Why Error Codes Go Astray
The core of the problem lies in how Magento handles translatable messages (Phrase objects) within the addProductsToCart process. When an error occurs, such as adding an unknown SKU or an invalid quantity, the system attempts to map the error message to a specific code (e.g., PRODUCT_NOT_FOUND, NOT_SALABLE). The issue arises because the Magento\Quote\Model\Cart\AddProductsToCart class prematurely calls ->render() on the Phrase object. This translates the message before it's passed to AddProductsToCartError::create() for error code mapping.
Consequently, AddProductsToCartError receives an already translated string (e.g., "Produit non trouvé SKU 'UNKNOWN_SKU'") and tries to match it against a lookup table that expects the original, untranslated English phrase. When no match is found, it defaults to the generic UNDEFINED error code.
Impact on Headless Commerce and PWA Implementations
This bug directly affects developers building robust headless frontends. These applications often rely on stable, programmatic error codes to display specific messages to users, trigger UI changes, or log errors effectively. Forcing frontends to parse and match translated error messages is a fragile and unsustainable workaround, especially in multi-language environments. It introduces unnecessary complexity and potential for breakage with future translation updates.
Consider the GraphQL query:
mutation {
addProductsToCart(
cartId: "CART_ID"
cartItems: [
{
sku: "UNKNOWN_SKU"
quantity: 1
}
]
) {
cart {
id
}
user_errors {
code
message
}
}
}While the expected result for a non-existing SKU in a French locale would be:
{
"user_errors": [
{
"code": "PRODUCT_NOT_FOUND",
"message": "Produit non trouvé SKU "UNKNOWN_SKU""
}
]
}The actual result, due to the bug, is:
{
"user_errors": [
{
"code": "UNDEFINED",
"message": "Produit non trouvé SKU "UNKNOWN_SKU""
}
]
}The Elegant Fix: Preserving the Original Phrase
The proposed solution is elegant and targets the root cause. It involves modifying Magento\Quote\Model\Cart\AddProductsToCart to pass the Phrase object directly, rather than its rendered string, to AddProductsToCartError::create(). Then, AddProductsToCartError::create() is updated to:
- Render the message only when constructing the final GraphQL error object for the user-facing message.
- Use
$message->getText()to retrieve the original, untranslated string for the error code mapping logic.
Here's a simplified view of the proposed PHP changes:
Before (in AddProductsToCart):
__('The product quantity should be greater than 0')->render()After (in AddProductsToCart):
__('The product quantity should be greater than 0')Proposed change in AddProductsToCartError::create():
use Magento\Framework\Phrase;
public function create(Phrase $message, int $cartItemPosition = 0): Data\Error
{
return new Data\Error(
$message->render(),
$this->getErrorCode($message->getText()),
$cartItemPosition
);
}This ensures that the user sees the correctly translated message, while the backend logic receives the untranslated text needed for accurate error code generation. A patch has also been provided in the GitHub issue for community review.
Community Insight and Next Steps
This issue, reported on Magento 2.4.x and labeled as 'ready for confirmation' with S3 severity, underscores the importance of meticulous handling of localization in core functionalities, especially within GraphQL APIs. For developers and merchants running multi-language Magento stores with headless frontends, this fix is crucial for maintaining a robust and predictable user experience. Community contributions and validation of such fixes are vital for the continuous improvement of the Magento platform.