EspoCRM version: 9.3.8
Outlook Integration extension version: 1.7.5 (also present in previous versions)
PHP version: 8.4
Database: PostgreSQL
Steps to Reproduce:
The phone number is cleared from the Outlook contact, matching the now-empty field in EspoCRM.
Actual behavior:
The old phone number remains on the Outlook contact. The sync job itself reports success; the removal is simply never applied on the Outlook side. Note that changing a phone number to a different, non-empty value syncs correctly - only clearing it to empty is affected.
Likely cause:
In ContactsManager:: pushContacts(), the phone number is only added to the update payload when it is non-empty. Existing contacts are updated via a PATCH request to Microsoft Graph. When the phone number is empty, "BusinessPhones" is omitted from the PATCH body entirely rather than being sent as an empty array. Microsoft Graph's PATCH semantics treat an omitted property as "leave unchanged", not "clear" - so the old value is never removed from the Outlook contact.
The same conditional pattern is used for "CompanyName" and "EmailAddresses" in the same method, so removing a contact's company name or email address likely has the same effect.
Outlook Integration extension version: 1.7.5 (also present in previous versions)
PHP version: 8.4
Database: PostgreSQL
Steps to Reproduce:
- Set up the Outlook integration and connect a user's Outlook account with Contact sync enabled.
- Create a Contact, assign it to that user, and set a phone number. Trigger the Outlook Contacts sync and confirm the phone number appears on the corresponding contact in Outlook.
- Edit the same Contact and remove the phone number entirely (clear the field), then save.
- Wait for the next Outlook Contacts sync job to run for this contact (it completes successfully / status "Success").
- Check the contact in Outlook.
The phone number is cleared from the Outlook contact, matching the now-empty field in EspoCRM.
Actual behavior:
The old phone number remains on the Outlook contact. The sync job itself reports success; the removal is simply never applied on the Outlook side. Note that changing a phone number to a different, non-empty value syncs correctly - only clearing it to empty is affected.
Likely cause:
In ContactsManager:: pushContacts(), the phone number is only added to the update payload when it is non-empty. Existing contacts are updated via a PATCH request to Microsoft Graph. When the phone number is empty, "BusinessPhones" is omitted from the PATCH body entirely rather than being sent as an empty array. Microsoft Graph's PATCH semantics treat an omitted property as "leave unchanged", not "clear" - so the old value is never removed from the Outlook contact.
The same conditional pattern is used for "CompanyName" and "EmailAddresses" in the same method, so removing a contact's company name or email address likely has the same effect.

Comment