function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Patrick TuitePatrick Tuite 

FIELD_INTEGRITY_EXCEPTION, You can’t change the completion date on a case milestone that’s already exited an entitlement process.


I'm trying to write a trigger for Case that will reopen or uncomplete the Final Milestone in the Entitlement Process for that Case. I have run up against getting an error
FIELD_INTEGRITY_EXCEPTION, You can’t change the completion date on a case milestone that’s already exited an entitlement process.
I am using a method expanded from the milestoneUtils code found here:

I tried adding @future against the method and while the error no longer occurs it does not uncomplete the Milestone going from Status 'Closed' to 'Open' the first time around.
However if I close the Case and then reopen subsequent times, it then does work.

Can anyone offer any insight into how I may correctly use the @future annotation so that it would work first time? Or any other way of dealing with this sequence of events?

This is my Trigger:
trigger openMilestoneOnReopenCase on Case (after update) {

    String finalMilestone = 'Solution Time';
    DateTime CompletionDate = NULL;
    List<Id> cases = new List<Id>();


        //Get the prior update Case states
        Case oldCaseState = Trigger.oldMap.get(c.Id);

        // Checking if this is a Case being reopend from Closed
        if(c.Status == 'Open' && oldCaseState.Status == 'Closed'){
            // Get the Case Milestone List
            List<CaseMilestone> caseMilestones = [Select MilestoneTypeId, IsCompleted from CaseMilestone cm where cm.MilestoneType.Name=:finalMilestone AND cm.CaseId=:c.Id];
            //Iterate the Case Milestone List
            for(CaseMilestone caseMilestone:caseMilestones){
                //Check the Solution Time state isCompleted and add the Case to the Case List
                if(caseMilestone.isCompleted == true){

            // Call the milestoneUtils Method
                milestoneUtils.reopenMilestone(cases, finalMilestone, completionDate);
This is the milestonesUtil Class I am calling the method from:
public class milestoneUtils {
    public static void reopenMilestone(List<Id> caseIds, String milestoneName, DateTime complDate) {
        System.debug('ASPD DEBUG: milestoneUtils: DateTime for completeMilestone is ' + string.valueOfGMT(complDate));

        List<CaseMilestone> cmsToUpdate = [select Id, completionDate from CaseMilestone cm where caseId in :caseIds and cm.MilestoneType.Name=:milestoneName and completionDate != null limit 1];
        if (cmsToUpdate.isEmpty() == false){
            for (CaseMilestone cm : cmsToUpdate){
                cm.completionDate = complDate;
            update cmsToUpdate;

Having the same issue myself. As mentioned, but can't seem to figure it out. I'm trying to complete a "Resolution" milestone when a case is closed on creation. As the milestones do not yet exist, I can't complete them, but I can't trigger any logic from the case milestone itself.
Patrick TuitePatrick Tuite
Can't seem to post? test
Patrick TuitePatrick Tuite
I got some time to look through this again and I was possibly hasty. The @future method does appear to work. Sometimes I need to refresh the page to see the Milestone uncompleted though. I guess there can be a little bit of a time delay.

I just wrote some code to have our First response time Milestone automatically completed on Case creation if the source if an inbound phone call. I had to use the @future method for that also. Some similar Apex should probably work for you

Can't seem to post with code tags though