mastra-ai/mastra · error · MastraError

SCHEDULES_ID_EXISTS

SCHEDULES_ID_EXISTS

Error message

schedules.create: a schedule with id "${id}" already exists. Use update() to modify it or choose a different id.

What it means

create() was called with a caller-supplied id that already exists in the schedules storage. The library treats create as create-only for explicit ids and throws a 409-class error directing you to update() instead.

Source

Thrown at packages/core/src/schedules/schedules.ts:401

      target,
      cron: input.cron,
      timezone: input.timezone,
      status: input.status ?? 'active',
      nextFireAt,
      createdAt: now,
      updatedAt: now,
      ...(input.metadata ? { metadata: input.metadata } : {}),
    };

    const created = await store.createSchedule(schedule);
    return toWorkflowSchedule(created)!;
  }

  async #assertIdAvailable(store: SchedulesStorage, id: string, callerProvided: boolean): Promise<void> {
    if (!callerProvided) return;
    const existing = await store.getSchedule(id);
    if (existing) {
      throw new MastraError({
        id: 'SCHEDULES_ID_EXISTS',
        domain: ErrorDomain.AGENT,
        category: ErrorCategory.USER,
        details: { status: 409 },
        text: `schedules.create: a schedule with id "${id}" already exists. Use update() to modify it or choose a different id.`,
      });
    }
  }

  async get(id: string): Promise<AnySchedule | null> {
    const schedule = await this.#load(id);
    if (!schedule) return null;
    return toScheduleView(schedule);
  }

  async list(filter?: ListSchedulesFilter): Promise<AnySchedule[]> {
    const store = await this.#getStore();
    const schedules = await store.listSchedules({

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Call schedules.update(id, patch) instead of create() when the schedule may already exist.
  2. Check existence first with getSchedule(id) (or a get/list call) and branch between create and update.
  3. Delete the existing schedule if recreation is intended, or choose a unique id.

Example fix

// before
await schedules.create({ id: 'daily-report', cron: '0 8 * * *' });
// after
const existing = await schedules.get('daily-report');
if (existing) {
  await schedules.update('daily-report', { cron: '0 8 * * *' });
} else {
  await schedules.create({ id: 'daily-report', cron: '0 8 * * *' });
}
Defensive patterns

Strategy: fallback

Validate before calling

const existing = await schedules.get('daily-report');
if (existing) throw new Error('exists — use update()');

Try / catch

try {
  await schedules.create({ id, ...config });
} catch (e) {
  if (String((e as Error).message).includes('already exists')) {
    await schedules.update(id, config);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling schedules.create() (or #createAgentSchedule/#createWorkflowSchedule) with an explicit id for which store.getSchedule(id) already returns a schedule.

Common situations: Re-running bootstrap/seed scripts that create schedules on every startup; deploying two instances that both create the same schedule id; typo where a schedule was created earlier and now is re-created with the same name.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/138f2b9054e0c358. Report an issue: GitHub.