Skip to content

INVALID_ID_FIELD error when RollupJob deletes schedule items concurrently with trigger upsert #1575

@s-kikuchi-safie

Description

@s-kikuchi-safie

GitHub Issue Draft for DLRS

Title

INVALID_ID_FIELD error when RollupJob deletes schedule items concurrently with trigger upsert


Issue Body

Description

When using Scheduled calculation mode, we occasionally encounter INVALID_ID_FIELD errors during the upsert of LookupRollupSummaryScheduleItems__c records. This occurs when the RollupJob batch is deleting schedule items at the same time a trigger is attempting to upsert new ones with the same QualifiedParentID__c.

Error Message

System.DmlException: Upsert failed. First exception on row 0; first error: INVALID_ID_FIELD, invalid record id: ()
(dlrs)
Trigger.dlrs_ReceiptDeliveryTrigger: line 7, column 1

Suspected Root Cause

We suspect this race condition may occur with the following sequence:

  1. T0: RollupJob starts deleting a schedule item (record may be locked)
  2. T1: Trigger executes upsert with same QualifiedParentID__c
    • Search by external ID finds the record (not yet deleted)
    • Attempts update, waits for lock
  3. T2: RollupJob commits deletion (record physically deleted)
  4. T3: Trigger's lock wait completes
    • Attempts to update a now-deleted record ID
    • Result: INVALID_ID_FIELD error

This appears to be a timing issue between the deletion process and the upsert operation.

Current Code Behavior

In RollupService.cls lines 1342-1361, only DUPLICATE_VALUE errors are ignored:

// iterate through errors, only return an exception for something other than DUPLICATE_VALUE
// because DUPLICATE_VALUE errors are usually sharing problems and we're happy as long as the record is in the database
for (Integer i = 0, j = results.size(); i < j; i++) {
  if (!results[i].isSuccess()) {
    for (Database.Error err : results[i].getErrors()) {
      if (err.getStatusCode() != System.StatusCode.DUPLICATE_VALUE) {
        throw new DmlException(
          'Upsert failed. First exception on row ' + i +
          '; first error: ' + err.getStatusCode() + ', ' +
          err.getMessage() + ': ' + err.getFields()
        );
      }
    }
  }
}

Proposed Solution

Treat INVALID_ID_FIELD the same as DUPLICATE_VALUE - ignore it because:

  1. It's a transient race condition: The schedule item will be recreated on the next trigger execution
  2. The parent record is already processed: If RollupJob deleted the item, it has already calculated the rollup
  3. Same logic as DUPLICATE_VALUE: As long as rollup processing occurs, the specific schedule item persistence doesn't matter

Suggested Code Change

for (Database.Error err : results[i].getErrors()) {
  if (err.getStatusCode() != System.StatusCode.DUPLICATE_VALUE
      && err.getStatusCode() != System.StatusCode.INVALID_ID_FIELD) {  // Add this
    throw new DmlException(...);
  }
}

Thank you for considering this issue!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions