mastra-ai/mastra · error
Notification ${current.id} is missing agentId
Error message
Notification ${current.id} is missing agentId What it means
sendNotificationRecord re-reads a notification from storage and delivers it to its agent. This error is thrown when the persisted notification record has no `agentId`, which is mandatory because the dispatcher needs it to resolve the target agent via mastra.getAgentById. It indicates a corrupted or hand-crafted notification record in storage.
Source
Thrown at packages/core/src/notifications/dispatcher.ts:142
});
}
async function sendNotificationRecord({
mastra,
storage,
record,
now,
batchThreadState,
}: {
mastra: Mastra;
storage: NotificationsStorage;
record: NotificationRecord;
now: Date;
batchThreadState?: NotificationDeliveryThreadState;
}): Promise<{ record: NotificationRecord; signal: CreatedAgentSignal } | null> {
const current = await storage.getNotification({ threadId: record.threadId, id: record.id });
if (!current || current.status !== 'pending' || current.deliveredSignalId) return null;
if (!current.agentId) throw new Error(`Notification ${current.id} is missing agentId`);
if (!current.resourceId) throw new Error(`Notification ${current.id} is missing resourceId`);
const agent = (await mastra.getAgentById(current.agentId as never)) as NotificationDispatchAgent;
const threadState =
batchThreadState ??
agentThreadStreamRuntime.getThreadState(
{ resourceId: current.resourceId, threadId: current.threadId },
agent.getPubSub?.(),
);
if (current.priority === 'high' && current.summarySignalId && threadState === 'active') return null;
const signal = createNotificationSignal({
...current,
status: 'delivered',
deliveredAt: now,
lastDeliveryAttemptAt: now,
});
const streamOptions = await resolveIfIdleStreamOptions(mastra, agent, { record: current, threadState, now });View on GitHub (pinned to 75dd419e61)
Solutions
- Inspect the offending record (storage.getNotification with its id/threadId) and re-create it through the official notification API so agentId is populated.
- Backfill agentId on affected rows in your storage (UPDATE notifications SET agentId = ... WHERE agentId IS NULL) for records that are still 'pending'.
- If the record is invalid and obsolete, delete it or mark it failed so the dispatcher skips it.
- Upgrade mastra / fix any custom storage adapter that silently drops agentId on write.
Example fix
// before (hand-inserted record)
await storage.saveNotification({ id: 'n1', threadId: 't1', resourceId: null, status: 'pending' });
// after
await storage.saveNotification({ id: 'n1', threadId: 't1', agentId: 'my-agent', resourceId: 'user-1', status: 'pending' }); Defensive patterns
Strategy: try-catch
Validate before calling
const rec = await storage.getNotification({ threadId, id });
if (rec && rec.status === 'pending' && !rec.agentId) {
logger.warn('Skipping notification with missing agentId', { id });
await storage.updateNotification({ id, threadId, status: 'failed', lastDeliveryError: 'missing agentId' });
} Type guard
function isDeliverable(rec: NotificationRecord | null): rec is NotificationRecord & { agentId: string; resourceId: string } {
return !!rec && rec.status === 'pending' && typeof rec.agentId === 'string' && typeof rec.resourceId === 'string';
} Try / catch
try {
await dispatchNotifications(mastra, storage, records, now);
} catch (err) {
if (err instanceof Error && /is missing agentId/.test(err.message)) {
const id = /Notification (.+) is missing agentId/.exec(err.message)?.[1];
logger.error('Corrupt notification record, marking failed', { id, err });
await storage.updateNotification({ id, threadId, status: 'failed', lastDeliveryError: err.message });
} else {
throw err;
}
} Prevention
- Only create notifications via the official notification APIs.
- Add a storage round-trip test verifying agentId survives save/get.
- Backfill agentId after migrations or version upgrades.
- Periodically scan storage for pending records with null agentId.
When it happens
Trigger: The dispatcher attempts delivery of a pending, not-yet-delivered notification whose stored record (returned by storage.getNotification) has a missing/empty agentId — typically a record created outside the normal notification-creation API or written by an older/buggy version.
Common situations: Manually inserting notification rows into the storage backend; a migration or older mastra version writing records without agentId; custom storage adapters that drop the agentId field; deleting/renaming agents and then patching stored records by hand.
Related errors
- Notification ${current.id} is missing resourceId
- Notification summary is missing agentId
- Version-control installation not found.
- Bound Factory work item not found.
- The related work item chain contains a cycle.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/199a8d66ff9d6bbc.
Report an issue: GitHub.