For anyone else landing here I was having a similar problem, but my client is actively using the preferred_communication_method in their workflow.
KarinG's answer pointed me in a direction that seems right and definitely works for me, with the issue being that the preferred_communication_method is treated as an array, and it looks to me like the error encountered in merging is due to code in the merge process that tries to explode the array and work with it.
This led me via an answer at https://stackoverflow.com/questions/47266517/civicrm-crm-core-daovalue-separator-how-to-use-it-in-pure-sql
to this immediate solution which lets the client keep using the field and have merges work correctly:
update civicrm_contact set preferred_communication_method=concat(X'01',2,X'01') where preferred_communication_method=2;
-with X'01' being the CRM_Core_DAO::VALUE_SEPARATOR
With this enacted (obviously for all relevant Integer values in addition to 2), all is fine.
Further note: in my case the reason the fields had an integer instead of an array to begin with is a module I have for taking live input from another CRM system. My next task is to fix this module (which uses the Civi API, not raw SQL) to populate this field with an array as expected.
Edit: On further research it was my use of the APIv3, which allows entering and will update with a string value, causing the merge problem. The solution is to ensure passing an array for preferred_communication_method.
My updated API call is now of the form
$result = civicrm_api3('Contact', 'create', array(
'contact_type' => "Individual",
'id' => $cid,
'preferred_communication_method' => array($pcm),
));