Q:

How can I use an ampersand character in a validation rule error message? 

I have a requirement to display the following message when an opportunity has is closed won in the wrong situation. 

Please make sure that the Renewal index field is filled in for all products, and if applicable, Gross Tonnage field is filled in for the P&I cover products. 

However when I save this into the error message field the & is transformed into &amp; in the metadata.  When the message is displayed to the user the &amp; is not converted back into &.  So I get this instead. 

Please make sure that the Renewal index field is filled in for all products, and if applicable, Gross Tonnage field is filled in for the P&amp;I cover products. 

I have tried amending the validation rule metadata xml to use <![ CDATA[&]]> as suggested here: https://stackoverflow.com/a/1328563 but Salesforce strips the tags and replaces & with &amp; when I edit the object metadata directly in eclipse.  When I use the web editor and write <![ CDATA[&]]> it converts all the special characters to &lt;![CDATA[&amp;]]&gt;. 
What can I do to get salesforce to display the '&' character correctly to the user? 
I just realised that I have a custom button performing the change of stage to Closed Won and this is trapping the validation error message and displaying it to the user via a javascript alert.  It is there that the ampersand is being transformed. 
Here is the custom button code
{! requireScript("/soap/ajax/13.0/connection.js")}
var oppName = '{! URLENCODE( LEFT(Opportunity. Name , 243))}';
var safeOppName = '{! URLENCODE( 'Checklist - ')}' + oppName;

if ('{! Opportunity. RecordTypeName__c}' == 'P_I' && {! Opportunity. Checklist_Count__c} == 0) {
window.location = '/a0j/e?CF00NM0000000aKxP='+oppName + '&&Name=' + safeOppName + '&&CF00NM0000000aKxP_lkid={!Opportunity. Id}' + '&&retURL={!Opportunity. Id}';
}
else {
var opp = new sforce. SObject("Opportunity");

opp. Id = "{! Opportunity. Id}";
opp. StageName = "Closed Won";

var result = sforce.connection.update([opp]);

if (result[0].success=='false')
{ alert(result[0].errors.message); }
else { 
location.reload(true); 
}
}

A:

The problem was in the custom button that was automating the opportunity closure.  It was displaying the validation error message in a javascript alert without decoding the &. 
As a very quick fix I have changed the code to replace any occurrence of &amp; with &.  Other solutions may exist but this seemed the quickest fix.  
The custom button code is now. 
{! requireScript("/soap/ajax/13.0/connection.js")}
var oppName =  '{! URLENCODE( LEFT(Opportunity. Name , 243))}';
var safeOppName =  '{! URLENCODE( 'Checklist - ')}' + oppName;

if ('{! Opportunity. RecordTypeName__c}' == 'P_I' && {! Opportunity. Checklist_Count__c} == 0) {
window.location = '/a0j/e?CF00NM0000000aKxP='+oppName + '&&Name=' + safeOppName + '&&CF00NM0000000aKxP_lkid={!Opportunity. Id}'  + '&&retURL={!Opportunity. Id}';
}
else {
var opp = new sforce. SObject("Opportunity");

opp. Id = "{! Opportunity. Id}";
opp. StageName = "Closed Won";

var result = sforce.connection.update([opp]);

if (result[0].success=='false')
{ var msg =  result[0].errors.message;
  var newmsg = msg.replace('&amp;','&');
alert( newmsg ); }
else { 
  location.reload(true); 
}
}

