Why Email Activity Parties Still Resolve to Unexpected Records Even After Changing an Email Column to Text

We had a custom text column on the Queue table that stored a shared mailbox address for reference. At some point the column was set up with the Email format, and several queues had the same address in that column. Later we changed the column format from Email to Text, because it was only for reference and wasn't meant to take part in email processing.


After that, incoming emails sent to that address kept resolving to all the queues that had the value in the custom column. They didn't resolve only to the queue whose primary email address matched. The format was no longer Email, but Dataverse was still matching the address to those queue records when it resolved the activity parties.

TL;DR: Changing a column's format from Email to Text doesn't remove its existing values from the internal EmailSearch table, so use the DoNotResolve flag (or clear the values while the column is still Email-formatted) before you change the format.

What is the EmailSearch Table?

Dataverse keeps an internal table called EmailSearch (emailsearch) that it uses for email address resolution. When server-side synchronisation processes an incoming email, it uses this table to match the sender and recipient addresses to records such as contacts, accounts, users and queues. Those matches become the activity parties on the email activity.

The platform maintains the table automatically. When a record is saved, the values in its Email-formatted columns are written to EmailSearch with a reference to the parent record. You can query it through the Web API:

GET [Organization URI]/api/data/v9.2/emailsearches?$filter=emailaddress eq 'shared.mailbox@example.com'

A few things to know about this table:

  • It isn't a cache, so there's no way to refresh it manually.
  • You can't delete or update its rows through the API or SDK. Others have hit the same limit, for example this community forum thread.
  • It only gets new values when a column is Email-formatted at the time the record is saved.
  • It doesn't keep a history of row changes.

Why the Values Became Stale

The column format is metadata only. According to Data type format conversions, a format tells the UI which control to use and doesn't validate or change the stored values. Changing the format from Email to Text doesn't touch the data in the column, and it doesn't touch the matching rows in EmailSearch either.

That leaves the EmailSearch rows orphaned:

  1. While the column was Email-formatted, saving each queue record added the address to EmailSearch.
  2. The format was changed to Text, and the rows in EmailSearch stayed where they were.
  3. Because the column is now Text, saving the record no longer updates or removes its EmailSearch rows.
  4. Server-side sync still finds those rows, so incoming emails keep resolving to every queue that had the address.

Since we can't delete EmailSearch rows directly, the only way to remove a value from EmailSearch is through the record itself: clear the Email-formatted column and save the record while the column still has the Email format.

Workaround

To clean up the stale rows:

  1. Temporarily change the column format back to Email.
  2. Clear the column value on every affected record and save each one. The matching EmailSearch rows are removed.
  3. Query the emailsearches endpoint to confirm that only the expected record still resolves the address.
  4. Change the column format back to Text and publish.
  5. Fill the column values back in if you still need them for reference. Now that the format is Text, they won't be added to EmailSearch.

This works, but you need to repeat it in every environment where the data exists.

Resolution: The DoNotResolve Flag

The supported option is the DoNotResolve flag, documented in Configure email address resolution behavior with the DoNotResolve flag. It lets you exclude a specific Email-formatted column from email resolution. The column keeps its Email format and its value, but server-side sync doesn't use it to match incoming emails.

The setting is stored in the Email Address Configuration table (emailaddressconfiguration), with one record for each table and column pair. There's no UI to create it, because the record looks up the Entity and Attribute metadata tables, so you create it with a Web API POST:

POST [Organization URI]/api/data/v9.2/emailaddressconfigurations

{
  "statecode": "1",
  "name": "Queue - Shared Mailbox Address - Do Not Resolve",
  "donotresolve": true,
  "AttributeId_EmailAddressConfiguration@odata.bind": "/attributes(<AttributeMetadataId>)",
  "EntityId_EmailAddressConfiguration@odata.bind": "/entities(<EntityMetadataId>)"
}

The best part is that this record is solution aware. You can create it once in DEV, add it to a solution and deploy it to the higher environments through your normal ALM process. There's no need to repeat the format change and data clean-up in each environment.


Recommendations

  • If a column needs to stay Email-formatted but shouldn't resolve incoming email, use DoNotResolve.
  • If you're converting an Email-formatted column to Text, first clear its values on all records and save them. Then confirm that resolution no longer uses the column, and only then change the format.
  • If emails are resolving to unexpected records, query the emailsearches endpoint by email address and check the _parentobjectid_value to see which records are matching.

Comments