mastra-ai/mastra · error · MastraError
SCHEDULES_MISSING_RESOURCE_ID
SCHEDULES_MISSING_RESOURCE_ID
Error message
Schedule${where}: 'resourceId' is required when 'threadId' is set. What it means
Mastra schedules support attaching a memory thread (`threadId`) to an agent schedule, but a thread can only be resolved when its owning resource is also given via `resourceId`. When a schedule definition sets `threadId` without `resourceId`, `assertValidScheduleDefinition` in packages/core/src/schedules/define.ts:226 throws SCHEDULES_MISSING_RESOURCE_ID so the invalid pair is rejected before it is persisted. This is a user-category validation error, raised at definition time (including for Markdown-defined schedules) rather than at fire time.
Source
Thrown at packages/core/src/schedules/define.ts:226
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
details: { label: label ?? '', signalType: String(definition.signalType) },
text: `Schedule${where}: unknown signalType "${definition.signalType}". Expected one of: ${SCHEDULE_SIGNAL_TYPES.join(', ')}.`,
});
}
if (definition.status !== undefined && !SCHEDULE_STATUSES.includes(definition.status)) {
throw new MastraError({
id: 'SCHEDULES_INVALID_STATUS',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
details: { label: label ?? '', status: String(definition.status) },
text: `Schedule${where}: unknown status "${definition.status}". Expected one of: ${SCHEDULE_STATUSES.join(', ')}.`,
});
}
if (definition.threadId && !definition.resourceId) {
throw new MastraError({
id: 'SCHEDULES_MISSING_RESOURCE_ID',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
details: { label: label ?? '' },
text: `Schedule${where}: 'resourceId' is required when 'threadId' is set.`,
});
}
}
/**
* Encode one component of a row id so it cannot contain the `__` delimiter.
*
* `encodeURIComponent` leaves `_` untouched, so escaping it explicitly is what
* actually makes the delimiter unambiguous — otherwise an agent named `a__b`
* and one named `a` with a key starting `_b` would produce the same row id.
* `decodeURIComponent` reverses `%5F` for free.
*/
function encodeRowIdPart(value: string): string {View on GitHub (pinned to 75dd419e61)
Solutions
- Add the matching `resourceId` (the resource that owns the thread) to the schedule definition alongside `threadId`.
- If the schedule should not use memory threads, remove `threadId` instead of adding a resourceId.
- Re-run/reload after fixing; for Markdown-defined schedules, correct the frontmatter/definition and reload the schedules.
Example fix
// before
mastra.defineSchedule({
id: 'daily-digest',
agentId: 'assistant',
prompt: 'Summarize the thread',
cron: '0 9 * * *',
threadId: 'thread_123',
});
// after
mastra.defineSchedule({
id: 'daily-digest',
agentId: 'assistant',
prompt: 'Summarize the thread',
cron: '0 9 * * *',
threadId: 'thread_123',
resourceId: 'user_42',
}); Defensive patterns
Strategy: validation
Validate before calling
function canDefineSchedule(def) {
return !(def.threadId && !def.resourceId);
}
if (!canDefineSchedule(def)) {
throw new Error('resourceId is required when threadId is set');
} Type guard
function hasResourceForThread(def): def is typeof def & { resourceId: string } {
return !def.threadId || typeof def.resourceId === 'string' && def.resourceId.length > 0;
} Try / catch
import { MastraError } from '@mastra/core/error';
try {
mastra.defineSchedule(def);
} catch (e) {
if (e instanceof MastraError && e.id === 'SCHEDULES_MISSING_RESOURCE_ID') {
console.error(`Schedule ${e.details?.label}: add resourceId or remove threadId`);
} else throw e;
} Prevention
- Always pair threadId with resourceId in schedule definitions.
- Run definition validation (assertValidScheduleDefinition) early in tests.
- Lint Markdown/YAML schedule files for threadId-without-resourceId.
When it happens
Trigger: Calling `mastra.getSchedule(...)`/`defineSchedule` (or `resolveSchedules`) with a definition object containing a truthy `threadId` and an undefined/empty `resourceId`, e.g. `{ agentId, prompt, cron: '0 9 * * *', threadId: 'thread_123' }` with no `resourceId`.
Common situations: Copy-pasting a schedule config that mentions threadId but omitting resourceId; wiring memory threads to scheduled agent prompts and assuming threadId alone identifies the thread; partially migrating configs where resourceId was added later; Markdown/YAML schedule files that only got the threadId field filled in.
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
- SCHEDULES_INVALID_DEFINITION
- SCHEDULES_MISSING_TARGET_ID
- SCHEDULES_AMBIGUOUS_MODE
- SCHEDULES_MISSING_MODE
- SCHEDULES_INVALID_SIGNAL_TYPE
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b0d7f74728118da0.
Report an issue: GitHub.