mastra-ai/mastra · error · MastraError

SCHEDULES_MISSING_TARGET_ID

SCHEDULES_MISSING_TARGET_ID

Error message

schedules.create requires `agentId` or `workflowId`.

What it means

`#createAgentSchedule` in packages/core/src/schedules/schedules.ts:275 validates that an agent-targeted schedule names the agent it should run. A schedule must target exactly one execution target, so if `agentId` is absent on an agent-schedule input (and no workflow target was chosen), `SCHEDULES_MISSING_TARGET_ID` is thrown. The message mentions `agentId` or `workflowId` because `create` dispatches between the two target kinds and one of them is required.

Source

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

    const canonical = canonicalizeScheduleId(trimmed, AGENT_SCHEDULE_PREFIX);
    if (!canonical || canonical === trimmed) return null;
    return store.getSchedule(canonical);
  }

  async create(input: CreateAgentScheduleInput): Promise<AgentSchedule>;
  async create(input: CreateWorkflowScheduleInput): Promise<WorkflowSchedule>;
  async create(input: CreateScheduleInput): Promise<AnySchedule> {
    if ('workflowId' in input && input.workflowId) {
      return this.#createWorkflowSchedule(input);
    }
    return this.#createAgentSchedule(input as CreateAgentScheduleInput);
  }

  async #createAgentSchedule(input: CreateAgentScheduleInput): Promise<AgentSchedule> {
    validateCron(input.cron, input.timezone);

    if (!input.agentId) {
      throw new MastraError({
        id: 'SCHEDULES_MISSING_TARGET_ID',
        domain: ErrorDomain.AGENT,
        category: ErrorCategory.USER,
        details: { status: 400 },
        text: 'schedules.create requires `agentId` or `workflowId`.',
      });
    }

    if (input.threadId && !input.resourceId) {
      throw new MastraError({
        id: 'SCHEDULES_MISSING_RESOURCE_ID',
        domain: ErrorDomain.AGENT,
        category: ErrorCategory.USER,
        details: { status: 400 },
        text: 'schedules.create requires `resourceId` when `threadId` is set.',
      });
    }
    if (!input.threadId) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Add `agentId` to the create input to target an agent: `schedules.create({ agentId: 'assistant', prompt, cron })`.
  2. Alternatively target a workflow by passing `workflowId` instead of `agentId`.
  3. Check for typos or undefined variables feeding the agentId field before calling create.

Example fix

// before
await schedules.create({ prompt: 'Run nightly summary', cron: '0 3 * * *' });

// after
await schedules.create({ agentId: 'assistant', prompt: 'Run nightly summary', cron: '0 3 * * *' });
Defensive patterns

Strategy: validation

Validate before calling

function hasScheduleTarget(input) {
  return Boolean(input.agentId) || Boolean(input.workflowId);
}
if (!hasScheduleTarget(input)) throw new Error('schedules.create requires agentId or workflowId');

Type guard

type ScheduleTarget = { agentId: string } | { workflowId: string };
function hasTarget(input: Record<string, unknown>): input is ScheduleTarget & Record<string, unknown> {
  return typeof input.agentId === 'string' || typeof input.workflowId === 'string';
}

Try / catch

try {
  await schedules.create(input);
} catch (e) {
  if (e instanceof MastraError && e.id === 'SCHEDULES_MISSING_TARGET_ID') {
    throw new Error('Add agentId (or workflowId) to the schedule create input');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `schedules.create({ prompt, cron, ... })` with neither `agentId` nor `workflowId` set — e.g. the input lacks `agentId`, so the create dispatcher routes it to `#createAgentSchedule`, which immediately fails the `if (!input.agentId)` check.

Common situations: Omitting the target when scaffolding a schedule from a template; a typo like `agent` instead of `agentId`; dynamically building the create input where the agent id is undefined at runtime; porting workflow schedules to agent schedules (or vice versa) and dropping the id field.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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