Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
All errors
Apex

The Apex job named "<name>" is already scheduled for execution

You called `System.schedule(name, ...)` with a name that's already in use. The platform refuses duplicate-name schedules. Either abort the existing one first, or pick a unique name (e.g., suffix with timestamp).

Also seen asalready scheduled for execution·Apex job is already scheduled·schedule name conflict

System.schedule(name, cronExp, jobInstance) requires name to be unique among active schedules. Reusing a name fails immediately.

The shape of the bug

System.schedule('Daily_Reconciliation', '0 0 1 * * ?', new ReconJob());
// Some time later, in the same org:
System.schedule('Daily_Reconciliation', '0 0 1 * * ?', new ReconJob());
// ❌ already scheduled

Fix 1: abort the old one before scheduling

List<CronTrigger> existing = [
    SELECT Id FROM CronTrigger
    WHERE CronJobDetail.Name = 'Daily_Reconciliation'
];
for (CronTrigger ct : existing) {
    System.abortJob(ct.Id);
}
System.schedule('Daily_Reconciliation', '0 0 1 * * ?', new ReconJob());

This pattern lets your deploy idempotently re-schedule the job — useful when you want the cron expression to update from one release to the next.

Fix 2: use a uniquely-suffixed name

String name = 'Daily_Reconciliation_' + System.now().getTime();
System.schedule(name, '0 0 1 * * ?', new ReconJob());

This bypasses the conflict but accumulates one new schedule per call. Watch for the scheduled-job-limit cap of 100. Most teams use Fix 1 (abort + re-schedule) for production schedules.

Fix 3: ScheduleBatch with a unique ID

For one-time deferred work, System.scheduleBatch returns a job ID and the name is auto-derived:

Id jobId = System.scheduleBatch(new MyBatch(), 'OneTime_' + UserInfo.getUserId(), 5);

The job runs once, 5 minutes from now. No persistent schedule to manage.

Diagnose: list all current schedules

SELECT Id, CronJobDetail.Name, NextFireTime, State, OwnerId
FROM CronTrigger
WHERE CronJobDetail.JobType = '7'   -- Scheduled Apex
ORDER BY CronJobDetail.Name

Run this in the Developer Console's Query Editor. Each row is one scheduled job. Look for duplicates or stale entries.

A common deploy-time issue

CI pipelines that include System.schedule calls in post-deploy hooks fail on the second run because the schedule from the first run is still active. Always pair the schedule with an upfront abort.

A clean post-deploy script pattern:

// In a deploy script or post-deploy class:
String JOB_NAME = 'Nightly_Reconciliation';
List<CronTrigger> existing = [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name = :JOB_NAME];
for (CronTrigger ct : existing) System.abortJob(ct.Id);
System.schedule(JOB_NAME, '0 0 2 * * ?', new ReconJob());

Idempotent. Re-run safe. Always.

Related dictionary terms