Summary
After upgrading to Magento 2.4.9 we encountered four bugs that cause fatal errors and broken syncs. All issues required patching vendor code via Magento DI plugins and a class preference override. We're reporting them together as they all became critical on 2.4.9.
Environment
- Magento: 2.4.9
- PHP: 8.4
- ActiveCampaign module-integration: 2.1.27
- Sub-package versions:
activecampaign/core: 2.1.30
activecampaign/customer: 2.1.21
activecampaign/order: 2.1.13
activecampaign/newsletter: 1.0.10
activecampaign/abandonedcart: 2.1.23
activecampaign/synclog: 2.1.6
Bug 1 — Customer sync crashes on invalid/empty email or missing name
Affected class: ActiveCampaign\Customer\Model\Customer::updateCustomer()
Symptoms:
- PHP warning:
Undefined array key 'data'
- ActiveCampaign API returns
422 email_invalid
- API returns
"First/Last Name is not valid!"
Cause: updateCustomer() does not validate the customer's email or name before sending the payload to the API. Guest checkouts and partially-filled accounts trigger these errors repeatedly.
Suggested fix: Add a guard at the start of updateCustomer() that returns early when email is empty/invalid or firstname/lastname is missing.
Bug 2 — Order sync cron crashes when product is null
Affected class: ActiveCampaign\Order\Model\OrderData\OrderDataSend::imageUrl()
Symptoms:
- Fatal error in
ac_order_sync_cron_job: Call to a member function getMediaGalleryImages() on null
- Entire cron job halts, blocking all pending order syncs
Cause: imageUrl() calls $product->getMediaGalleryImages() without a null check. This happens for orders containing products that have since been deleted or are unavailable.
Suggested fix:
if ($product === null) {
return '';
}
Bug 3 — Repeated 422 "duplicate" errors when re-syncing orders
Affected class: ActiveCampaign\Core\Helper\Curl (ecomOrder POST)
Symptoms:
- API returns
422 or 400 with error code duplicate when an order is synced more than once
- No automatic recovery; orders remain permanently out of sync
Cause: The integration always POSTs to create a new ecomOrder. If the order was previously synced (e.g. after a re-index or manual re-sync), the API rejects it as a duplicate with no fallback.
Suggested fix: When a POST returns a duplicate error, look up the existing ecomOrder by externalid (Magento order ID) and retry the request as a PUT to update the existing record.
Bug 4 — Null response keys cause fatal errors in orderDataSend()
Affected class: ActiveCampaign\Order\Model\OrderData\OrderDataSend::orderDataSend()
Symptoms:
- Fatal errors / uncaught exceptions during order sync
Undefined index / Trying to access array offset on null on $response['ecomOrders']
Cause: The method accesses API response keys directly without null-coalescing. Under certain conditions (rate limits, partial responses, missing billing email) these keys are absent.
Suggested fix: Use null-coalescing operators (?? [], ?? null) on all API response array accesses, and initialize output arrays before any foreach loop.
Summary
After upgrading to Magento 2.4.9 we encountered four bugs that cause fatal errors and broken syncs. All issues required patching vendor code via Magento DI plugins and a class preference override. We're reporting them together as they all became critical on 2.4.9.
Environment
activecampaign/core: 2.1.30activecampaign/customer: 2.1.21activecampaign/order: 2.1.13activecampaign/newsletter: 1.0.10activecampaign/abandonedcart: 2.1.23activecampaign/synclog: 2.1.6Bug 1 — Customer sync crashes on invalid/empty email or missing name
Affected class:
ActiveCampaign\Customer\Model\Customer::updateCustomer()Symptoms:
Undefined array key 'data'422 email_invalid"First/Last Name is not valid!"Cause:
updateCustomer()does not validate the customer's email or name before sending the payload to the API. Guest checkouts and partially-filled accounts trigger these errors repeatedly.Suggested fix: Add a guard at the start of
updateCustomer()that returns early whenemailis empty/invalid orfirstname/lastnameis missing.Bug 2 — Order sync cron crashes when product is null
Affected class:
ActiveCampaign\Order\Model\OrderData\OrderDataSend::imageUrl()Symptoms:
ac_order_sync_cron_job:Call to a member function getMediaGalleryImages() on nullCause:
imageUrl()calls$product->getMediaGalleryImages()without a null check. This happens for orders containing products that have since been deleted or are unavailable.Suggested fix:
Bug 3 — Repeated 422 "duplicate" errors when re-syncing orders
Affected class:
ActiveCampaign\Core\Helper\Curl(ecomOrder POST)Symptoms:
422or400with error codeduplicatewhen an order is synced more than onceCause: The integration always POSTs to create a new ecomOrder. If the order was previously synced (e.g. after a re-index or manual re-sync), the API rejects it as a duplicate with no fallback.
Suggested fix: When a POST returns a
duplicateerror, look up the existing ecomOrder byexternalid(Magento order ID) and retry the request as a PUT to update the existing record.Bug 4 — Null response keys cause fatal errors in
orderDataSend()Affected class:
ActiveCampaign\Order\Model\OrderData\OrderDataSend::orderDataSend()Symptoms:
Undefined index/Trying to access array offset on nullon$response['ecomOrders']Cause: The method accesses API response keys directly without null-coalescing. Under certain conditions (rate limits, partial responses, missing billing email) these keys are absent.
Suggested fix: Use null-coalescing operators (
?? [],?? null) on all API response array accesses, and initialize output arrays before anyforeachloop.