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
Sumant KuchipudiSumant Kuchipudi 

ProcessBuilder failing with "Future method cannot be called from a future or batch method: " error

Hi,
I have a process builder which calls Apex method (@InvocableMethod) and the apex method calls future callout, this process is failing with the below error. I have the code checking !system.isFuture() but still failing, not able to figure out.
Error element myRule_1_A1 (FlowActionCall).
An Apex error occurred: System.AsyncException: Future method cannot be called from a future or batch method: AddressValidateController.invokeAddressController(List)
Apex Code is below.
global with sharing class AddressValidateController {
    public static boolean isVerified = false;
   
	@InvocableMethod
    global static void validateAddressFromPB(List<Id> recIds){
       
        if(!system.isFuture() && !isVerified){
            integer count = 0;
            List<String> subList = new List<String>();
            for (Id recId:recIds){
                count+=1;
                subList.add(recId);
                if (Math.Mod(count, 100)==0){
                    invokeAddressController(subList);
                    subList=new List<String>();
                }
            }
            invokeAddressController(subList);
            isVerified = true;
        }
    }
    
    
	@future(callout=true)
    global static void invokeAddressController(List<Id> recIds){
        
               Address validation callout code here
    }
}

Please advice..!
 
Raj VakatiRaj Vakati

As the error states you are calling a future method from another future method .

Hence would suggest to keep only one method and do all future operations in a single future class like below 
 
global with sharing class AddressValidateController {
    public static boolean isVerified = false;
   
	@InvocableMethod
    global static void validateAddressFromPB(List<Id> recIds){
       
        if(!system.isFuture() && !isVerified){
            integer count = 0;
            List<String> subList = new List<String>();
            for (Id recId:recIds){
                count+=1;
                subList.add(recId);
                if (Math.Mod(count, 100)==0){
                  // remove this method---> invokeAddressController(subList);
				  
				  // call the logic direcly Address validation callout code here
                    subList=new List<String>();
                }
            }
            invokeAddressController(subList);
            isVerified = true;
        }
    }
    
    
	
}

 
Auloh HuronAuloh Huron
Hi,

There is a salesforce limitation that you can not call future methods from batch. To avoid this error you can keep one flag in batch class and check that flag in Account trigger, if it is coming from batch do not call that future method.

Batch class

public static accountBatchFlag = false

Before performing any updates/inserts you can make this flag as true in batch


In trigger you can check the condition if accountBatchFlag is false then call future method. this way you can avoid error.

https://mcdvoice.me
Sumant KuchipudiSumant Kuchipudi
Thanks Auloh Huron, yes I think this one is calling from batch and yours seems to be good solution, let me try.
Nazim Altinay 6Nazim Altinay 6
This question is on Top google search, I lived same problem and solved it. May be it helps other person.

The reason was Future method is fired twice before COMMIT in my case. 

My flow was working on Update/create and class was updating data in future method and it caused to fire future method twice.

I added an extra if condition to prevent  fire twice and it isolved.

Nazim Altinay