+ Start a Discussion
Robert Goldberg 9Robert Goldberg 9 

Lead Conversion Apex Errors

I've spent the last 2 days trying to make some sense of this, and it's killing me.  We have a process wherein leads can either be (1) created with a unique identifier and then are auto-converted (a process which works fine) or (2) are updated after creation (could be hours or days later) with information from our external system, that adds a unique identifier.

I am trying to write a trigger that will recognize this change, and then subsequently convert the lead.

Tests fine, works in sandbox.  In production, I get this error:

Lead DetailError:Apex trigger AgentAdded caused an unexpected exception, contact your administrator: AgentAdded: execution of AfterUpdate caused by: System.DmlException: ConvertLead failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, System.DmlException: Update failed. First exception on row 0 with id 00Qo000000J8ITAEA3; first error: CANNOT_UPDATE_CONVERTED_LEAD, cannot reference converted lead: [] (System Code) : []: Trigger.AgentAdded: line 21, column 1

If anyone can advise on how I should update my trigger, it would be a massive help.  My trigger & test class are below.  Thanks!

Trigger:

Trigger AgentAdded on Lead (after insert, after update) {
LeadStatus convertStatus = [
select MasterLabel
from LeadStatus
where IsConverted = true
limit 1
];
List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
 
for (Lead lead: Trigger.new) {
if (!lead.isConverted && Lead.Agent_ID__c!='0' && Lead.Agent_ID__c !=NULL && Lead.Manually_Routed__c!='TRUE' && Lead.Auto_Assigned__c==FALSE && Lead.Auto_Route__c!='TRUE')
{Database.LeadConvert lc = new Database.LeadConvert();
String oppName = lead.Name;
lc.setLeadId(lead.Id);
lc.setOpportunityName(oppName);
lc.setConvertedStatus(convertStatus.MasterLabel);
leadConverts.add(lc);}
}
 
if (!leadConverts.isEmpty()) {
List<Database.LeadConvertResult> lcr = Database.convertLead(leadConverts);
}
}

TestClass:

@IsTest
private class AgentAddTest {
private static Integer LEAD_COUNT = 0;
private static Lead createLead() {
LEAD_COUNT += 1;
return new Lead(
FirstName = '_unittest_firstname_: ' + LEAD_COUNT,
LastName = '_unittest_lastname_: ' + LEAD_COUNT,
Metro__c='New Jersey'+ LEAD_COUNT,
Status = 'Unread'
);
}
public static void makeFreeTrial(Lead lead) {
lead.Agent_Added__c = TRUE;
lead.agent_id__c='100345678';
}
public static List<Lead> fetchLeads(Set<Id> ids) {
return [
select isConverted
from Lead
where Id in :ids
];
}
public static testMethod void trialConvert() {
Lead testLead = createLead();
makeFreeTrial(testLead);
 
Test.startTest();
insert testLead;
Test.stopTest();
List<Lead> results = fetchLeads(new Set<Id>{testLead.Id});
System.assertEquals(1, results.size(), 'Did not get the right number of leads back');
System.assert(results.get(0).isConverted, 'The lead should have been converted since it was a "Free Trail"');
}
 
public static testMethod void nonTrialNoConvert() {
Lead testLead = createLead();
Test.startTest();
insert testLead;
Test.stopTest();
List<Lead> results = fetchLeads(new Set<Id>{testLead.Id});
System.assertEquals(1, results.size(), 'Did not get the right number of leads back');
System.assert(!results.get(0).isConverted, 'The lead should not have been converted since it was not a "Free Trial"');
}
public static testMethod void bulkTest() {
List<Lead> shouldBeConverted = new List<Lead>();
List<Lead> shouldNotBeConverted = new List<Lead>();
for (Integer i = 0; i < 50; i++) {
Lead testLeadNonConvert = createLead();
Lead testLeadConvert = createLead();
makeFreeTrial(testLeadConvert);
shouldBeConverted.add(testLeadConvert);
shouldNotBeConverted.add(testLeadNonConvert);
}
List<Lead> toInsert = new List<Lead>();
toInsert.addAll(shouldBeConverted);
toInsert.addAll(shouldNotBeConverted);
Test.startTest();
insert toInsert;
Test.stopTest();
Map<Id, Lead> expectedConversions = new Map<Id, Lead>(shouldBeConverted);
Map<Id, Lead> expectedNonConversions = new Map<Id, Lead>(shouldNotBeConverted);
Set<Id> leadIds = new Set<Id>();
leadIds.addAll(expectedConversions.keySet());
leadIds.addAll(expectedNonConversions.keySet());
for (Lead result: fetchLeads(leadIds)) {
if (expectedConversions.containsKey(result.Id)) {
System.assert(result.isConverted, 'This lead should have been converted ' + result);
expectedConversions.remove(result.Id);
} else if (expectedNonConversions.containsKey(result.Id)) {
System.assert(!result.isConverted, 'This lead should not have been converted ' + result);
expectedNonConversions.remove(result.Id);
} else {
System.assert(false, 'We got a Lead we did not expect to get back ' + result);
}
}
System.assert(expectedConversions.isEmpty(), 'We did not get back all the converted leads we expected');
System.assert(expectedNonConversions.isEmpty(), 'We did not get back all the non converted leads we expected');
}
}
Vj@88Vj@88
Hi Robert,

Try including the line LeadConverts.clear();  at the end of trigger
Robert Goldberg 9Robert Goldberg 9
Sadly, I got the exact same error.


Error:Apex trigger AgentAdded caused an unexpected exception, contact your administrator: AgentAdded: execution of AfterUpdate caused by: System.DmlException: ConvertLead failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, System.DmlException: Update failed. First exception on row 0 with id 00Qo000000J8ITAEA3; first error: CANNOT_UPDATE_CONVERTED_LEAD, cannot reference converted lead: [] (System Code) : []: Trigger.AgentAdded: line 21, column 1
 
Vj@88Vj@88
Can you check once if there are any fields updates happening through Work flows?
Robert Goldberg 9Robert Goldberg 9
There are, but none that are affecting these leads in particular.  In theory, a lead is created, and then a particular field updated by an external system, which should kick off this trigger.  None are actually post-workflow updates.
Robert Goldberg 9Robert Goldberg 9
I have disabled all workflows on all objects, and this still isn't working.  Anyone have any ideas?