In a batch Apex class, I've wrapped the DML statements in a transaction and try/catch block, looking for DMLExceptions. When I catch the exception and call getDMLId(), it just returns null, which is not useful in tracking down the error.

Simplified Code:

global void execute(Database.BatchableContext bc, List<sObject> scope){
  System.Savepoint rollbackPoint = Database.setSavepoint();
    UpdateRecords(scope);  //Updates existing records
  catch(DMLException e){
    for (Integer index = 0; index < e.getNumDml(); index++){
      this.batchErrorMessage = this.batchErrorMessage + '\nThe job failed for record ' + e.getDmlId(index) + ' on fields ' + e.getDmlFieldNames(index) + '.';   
      this.batchErrorMessage = this.batchErrorMessage + '\nException message: ' + e.getDmlMessage(index);


Sample message:

The job failed for record null on fields (My_Field__c). Exception message: My_Field__c outside of valid range on numeric field: My_Field__c

The record is failing during an UPDATE, so I know the record id exists. Why is getDmlId() returning null while the other methods don't? How can I

2 Answers 2


Perhaps someone can answer the question of why the method is returning null.

All I can offer is a work-around to use scope[e.getDmlIndex(index)].Id instead of e.getDmlId(index) in the error message. (With the hope that getDmlIndex does not also return null.)

  • This worked, but I had to move the error handling into my function call (there are multiple DML operations, so each is in a distinct try/catch block now.)
    – Mike Chale
    Apr 8, 2014 at 0:53

Encountered with similar problem.

It seems like there is a difference in behaviour when you are using simple update statement VS going with Database.update. In latter case DMLException really does not return affected record id.

So just switching to ordinary update statement has solved the problem in my case, i.e. got non-null id as exp.getDmlId(0).

You must log in to answer this question.

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