I am creating a trigger which upon creation of a lead, searches for any contacts with a matching email, and if found - convert the lead, and set the ContactId on the lead. I am just having some trouble figuring out how to create a map, I think it should be <LeadId, ContactId> and then pass this to the Database.leadconvert class to set the contactId.

Forgive me - admin trying to be a dev. Thank you for any help!

trigger convertLead on Lead (after insert) {

// Leads Set
Set<String> formLeads = new Set<String>();
// Loop through leads, store in set when FORM == TRUE
for(Lead l : Trigger.New) {
    if(l.Form_Submission_ADMIN_USE_ONLY__c == True) {
        l.Description = 'Trigger ran';
// List of contacts - Select contacts when email IN emailstocompare
List<Contact> matchingCons = [SELECT Id, Email FROM Contact 
                                WHERE Email IN :formLeads];
// create Map of email and contactId
Map<String, Id> emailToContactId = new Map<String, Id>();

for(Contact con:matchingCons) {
    emailToContactId.put(con.Email, con.Id);
List<Database.LeadConvert> leadConvert = new List<Database.LeadConvert>();
LeadStatus convertStatus = [SELECT MasterLabel FROM LeadStatus 
WHERE IsConverted = true LIMIT 1];

if(matchingCons.size()>0) {
    if ((Trigger.isAfter)&&(Trigger.isInsert)){
        for(Lead l : Trigger.New) {
            // convert lead
            Database.LeadConvert lc = new Database.LeadConvert();
        List <Database.LeadConvertResult> lcr = Database.convertLead(leadConvert); 
        for(Integer i=0; i < lcr.size(); i++){


  • there is no ID on Lead in a beforeInsert trigger; you should do this in afterInsert
    – cropredy
    Oct 22, 2020 at 19:26
  • Hey.. thank you! I have since updated to an after insert trigger and updated re the suggestion below.. but now getting this error.. System.FinalException: Record is read-only () Oct 22, 2020 at 19:32
  • delegate the lead conversion to a future or queueable
    – cropredy
    Oct 22, 2020 at 22:33

1 Answer 1


I read the apex dev guide for the LeadConvert class (Since I have never used it) and I went through your code snippet. Following is my understanding :

  • The convertLead Database method converts a lead into an account and contact, as well as (optionally) an opportunity.
  • In your case, If the Contact's(already present in system) email matches Lead's email, merge the lead into the same contact.

See the code below (Mark this as an answer if it's helpful) :

// List of contacts where email matches
// formLeads is a Set of Lead emails
List<Contact> matchingCons = [SELECT Id, Email FROM Contact 
                            WHERE Email IN :formLeads];

//create a map of email and contactId
Map<String, Id> emailToContactIdMap = new Map<String, Id>(); 
for(Contact con : matchingCons){

  emailToContactIdMap.put(con.Email, con.Id);

//Loop over Trigger.new get all the Lead Ids
List<Id> newLeadIds = new List<Id>();
for(Lead l : Trigger.new){
List<Lead> leadsToConvert = [SELECT id, 'put all required fields' from Lead 
                            where Id IN: newLeadIds];

List<Database.LeadConvert> leadConvertList =new List<Database.LeadConvert>();
if(matchingCons.size() > 0){ // If contacts are matching

 for(Lead l : leadsToConvert) {     
    // convert lead
    Database.LeadConvert lc = new Database.leadConvert();
    //Fetching contactId using the Lead's email
    //If the Lead's email & contact's email match,
    //"emailToContactIdMap" will have an entry for it

    database.LeadConvertResult lcr = Database.convertLead(leadConvertList); 

  • Thanks so much for your help - I have adjusted and the code is passing. I am now receiving the error when I test and create a new lead - convertLead: execution of AfterInsert caused by: System.FinalException: Record is read-only () So I added if(l.isConverted==false) {convert lead} just inside the for loop, and it is still giving me the error, but it sounds like the lead is converting - amazing. I am just googling the exception.. would you have any ideas? Thank you! Oct 22, 2020 at 16:51
  • Not sure why I missed this. I have updated my answer above. Better way of doing this is building a List<Database.LeadConvert> in the loop, and calling the Database.convertLead method for the whole list outside the loop. Check if this solves the exception also. Please mark my response as the answer if it helps. Thanks ! Oct 22, 2020 at 17:30
  • Thank you! I still seem to be getting the same error.. I updated the code per your suggestion above, does database.leadconvert need to go through a different lead loop that is not Trigger.new? Oct 22, 2020 at 18:10
  • This error is coming because you are in an after insert context and the records are read only in that context as they have been written, but not committed, to the database. Unfortunately yo need the Lead Id for the Lead conversion, so you can't use the before insert context. There are 2 possible ways technically to resolve this : 1st --> as @cropredy has pointed out in the above comments, "delegate the lead conversion to a future or queueable method". 2nd --> Clone the lead record, and do the conversion for the cloned record. The 1st approach should be the best approach in this scenario Oct 23, 2020 at 9:40
  • In the 2nd approach, you can also query the whole Trigger.new again via SOQL and do the Lead conversion on that List. Check my updated answer above Oct 23, 2020 at 9:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.