Skip to content

deleteWhenMissingModels breaks batch job counting, preventing finally callback from executing #58528

@yankewei

Description

@yankewei

Laravel Version

12.46.0

PHP Version

8.4.0

Database Driver & Version

No response

Description

When a batch job uses $deleteWhenMissingModels = true and the model is hard-deleted before the job is processed, the job is silently deleted but the batch's pendingJobs counter is never decremented. This causes the finally callback to never execute.

Expected Behavior:

The batch's finally callback should execute when all jobs have been processed (including those skipped due to missing models).

Actual Behavior:

The finally callback never executes because pendingJobs - failedJobs !== 0.

Root Cause:

In CallQueuedHandler::handleModelNotFound(), when $deleteWhenMissingModels = true, the job is deleted directly without updating the batch status:

protected function handleModelNotFound(Job $job, $e)
{
    // ...
    if ($shouldDelete) {
        return $job->delete();  // Batch is never notified
    }
    return $job->fail($e);
}

The normal flow in call() updates the batch before deleting:
$this->ensureSuccessfulBatchJobIsRecorded($command); // First update batch
$job->delete(); // Then delete job

Steps To Reproduce

  1. Create a job with Batchable trait and $deleteWhenMissingModels = true
  2. Dispatch the job as part of a batch with a finally callback
  3. Hard-delete the model before the job is processed
  4. Process the queue

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions