I need to assign leads to users with a custom logic. So I would like to change the OwnerId to a new one selected during apex trigger call.

I saw that it was not possible to change fields on Lead with an after insert trigger due to execution of AfterInsert caused by: System.FinalException: Record is read-only. The same happens even if I create a public class with a static method containing @InvocableMethod and call it from Process builder after the record has been created.

So now I'm doing it trigger MyTrigger on Lead (before insert). But after a lead is created from a web-2-salesforce I see that leads is not owned by a user selected with my custom logic but from a flow. During troubleshooting I found out that the flow runs after the before insert trigger.

Any suggestion would be helpful.

  • 1
    why not a before insert trigger?
    – cropredy
    Commented May 26, 2020 at 22:22
  • You are right @cropredy. It's before insert trigger and it was a typo in my question.
    – Edmond
    Commented May 27, 2020 at 6:10
  • 1
    do you also have Lead assignment rules configured? They will run after the before insert trigger
    – cropredy
    Commented May 27, 2020 at 17:45
  • Yes, I just found out that I do have lead assignments and removed(disabled) them. When I put the user that is responsible for web-to-lead in debug/trace and view logs after sending a lead with Postman I do see that my Lead trigger is run and I see the logic working good and selecting one OwnerId and setting it to it. Logs: VARIABLE_ASSIGNMENT|[35]|this.OwnerId|"0050_USER_ID"|. But when I go and check the leads I see that it has been assign to another user...
    – Edmond
    Commented May 27, 2020 at 22:09
  • 1
    please include edit the debug log exposing only Workflows, Apex (everything else as NONE) and rerun from web2lead (then compare to Postman). Web2Lead will execute assignment rules; postman will not unless you tell sfdc to using assignment rule headers
    – cropredy
    Commented May 27, 2020 at 23:57

2 Answers 2


If you want to preempt the Lead Assignment rules (while keeping them active):

  • for certain Leads created by any client
  • where such client instructs SFDC to run lead assignment rules (such as Web-to-Lead)

do the following:

  • Add a custom field to the Lead - Has_Preemptively_Assigned_Owner__c (checkbox, default to false)
  • Add as the VERY FIRST lead assignment rule a condition Has_Preemptively_Assigned_Owner__c = true with action = Do not reassign owner
  • Amend your before insert trigger to run custom logic that sets the Lead.OwnerId and also sets Has_Preemptively_Assigned_Owner__c = true

Then, since order of execution runs Lead Assignment rules following the before/after insert trigger (see step 9), the assignment rules will simply fall out and do nothing. Leads with Has_Preemptively_Assigned_Owner__c = false will run through the lead assignment rules.


Hope this help. My customer needed a solution that distributed Leads evenly based on "number of widgets" (1-2, 3-5, 6-10 etc.) that's selected from the pick list on the company's contact-us form, however it could be easily adapted to go off Lead Source or the number of Leads a rep currently owns or has been previously assigned, or other custom logic. Overall, my customer's need was (based on deal size) to have incoming Web-to-Leads evenly distributed between 3 reps BUT also have the ability to assign the Leads to 2 completely different reps based on the number of a specific Task Type they Completed the week prior. Essentially resulting in two groups: 3 that are in a "Round Robin" and the other 2 that get "Bonus Leads" based on their prior week's performance. I used two custom objects Lead Distro/Rep (master/detail), two Process Builder flows, one Flow and two scheduled DLRS. The Lead Distro object is the "scoreboard" that stores all the values for the Flow to use when evaluating the assignment and the Rep object has a lookup to their SFDC User Record, their “Round Robin” number (1-3), the total number of Bonus Leads they should get, and then the number of Leads remaining that they have yet to receive Lead Distro Scoreboard ...and here's how everything works: Every Monday morning at 12:00am a scheduled rollup calculation (DLRS) counts the specific Tasks Types and saves this number to their SFDC User Record. Right after this a 2nd DLRS runs on a formula field on the Rep Object that shows the number of Bonus Leads from the User Object and saves it to number field on Lead Distro Record "Bonus Leads Left to Assign." This change is necessary to fire a Process builder on the Rep (Rep__r) records to take the number of Bonus Leads they should get and add it to the value of the Leads they have left to receive. Next is the Process Builder on Lead, and all the criteria for it to evaluate if it needs to go to Lead Distro scoreboard. If it does, I update a lookup field on the Lead to the Lead Distro Record (there's only one) and under that action set a lookup on the Lead Distro Record back to the same Lead. (Lead comes in, lookup to Lead Distro Record is set, lookup field on the Lead Distro Record is set back to the same Lead) When the lookup field on the Lead Distro Record is set with the Lead, this fires the Autolaunched Flow. The flow evaluates if there are Bonus Leads that need to be assigned. If yes, it grabs all the users that are NOT in the Round Robin, and then sorts it based on who has the highest number of "Number of Bonus Leads Left to Assign" at the top. (For example if Bob has 3 Bonus Leads and Jane had 1, Bob would get the next TWO incoming Leads.) After the Lead is assigned, the number left to get assigned is reduced by -1 on their Rep Record, and the Email Alert is sent out. Once all the Bonus Leads have been assigned, it proceeds with the “Round Robin” (Default Outcome in the pic below) and evaluates (again based on ”number of widgets") who was it assigned to the previous time and who should it be assigned to now. There’s a number field for each value in the pick list and the flow adds a +1 based on the value that the Lead has. For example if it's 1, it's changed to 2, until it equals the "Number of Reps in Round Robin" and then starts over, that way if a new person is added to the Round Robin (increasing it to a total of 4 reps) nothing has to be done and the system will assign until it reaches 4, then start over at 1. This is done using a Case() method with an IF statement to evaluate if incrementing the value +1 exceeds the total "Number of Reps in Round Robin" (Rollup Summary field) in a formula resource in the flow: Case({!LeadDistroObject.LeadLookupField__r.NumberofWidgetsField__c},

"0-1", If({!LeadDistroObject.CurrentValueFor0_1__c}+1 > {!LeadDistroObject.NumberofRepsinRoundRobin__c},1, {!LeadDistroObject.CurrentValueFor0_1__c}+1),

"2-5", If({!LeadDistroObject.CurrentValueFor2_5__c}+1 > {!LeadDistroObject.NumberofRepsinRoundRobin__c},1, {!LeadDistroObject.CurrentValueFor2_5__c}+1), ...etc


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .