mastra-ai/mastra · error
Notification ${current.id} is missing resourceId
Error message
Notification ${current.id} is missing resourceId What it means
sendNotificationRecord requires the stored notification to have a `resourceId`, since it routes signals to the agent keyed by resourceId + threadId and uses resourceId for thread state lookup. This error is thrown when the pending notification record lacks a resourceId.
Source
Thrown at packages/core/src/notifications/dispatcher.ts:143
}
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 });
const target: SendAgentSignalOptions = {View on GitHub (pinned to 75dd419e61)
Solutions
- Re-create the notification via the official API, always passing the resourceId of the owning user/resource.
- Backfill resourceId on existing pending rows in your storage for affected records.
- Delete or fail-terminate invalid records so the dispatcher can skip them.
- Verify your storage adapter preserves resourceId on save/update (add a round-trip test).
Example fix
// before
await createNotification({ agentId: 'my-agent', threadId: 't1', message: 'hi' }); // no resourceId
// after
await createNotification({ agentId: 'my-agent', resourceId: 'user-1', threadId: 't1', message: 'hi' }); Defensive patterns
Strategy: validation
Validate before calling
if (!notification.resourceId) {
throw new TypeError('Cannot create a notification without a resourceId');
}
await createNotification({ ...notification, resourceId: String(notification.resourceId) }); Type guard
function hasResourceId(rec: NotificationRecord): rec is NotificationRecord & { resourceId: string } {
return typeof rec.resourceId === 'string' && rec.resourceId.length > 0;
} Try / catch
try {
await dispatchNotifications(mastra, storage, records, now);
} catch (err) {
if (err instanceof Error && /is missing resourceId/.test(err.message)) {
const id = /Notification (.+) is missing resourceId/.exec(err.message)?.[1];
logger.error('Notification record missing resourceId, marking failed', { id });
await storage.updateNotification({ id, threadId, status: 'failed', lastDeliveryError: err.message });
} else {
throw err;
}
} Prevention
- Make resourceId a required parameter in your notification-creation wrapper.
- Check storage schema/migrations to ensure resourceId is NOT NULL for pending records.
- Test custom storage adapters for resourceId round-trip fidelity.
- Sweep storage for pending records with null resourceId after imports/migrations.
When it happens
Trigger: Delivery of a pending notification whose storage record has an empty/missing resourceId — e.g. the record was created without the resource identifier, or a storage layer/migration stripped it. The dispatcher reads the fresh record via storage.getNotification and throws before calling getThreadState.
Common situations: Creating notifications without supplying the resourceId your app tracks users by; custom storage adapters omitting the field on serialization; schema migrations that made resourceId nullable; importing notification data from another system.
Related errors
- Notification ${current.id} is missing agentId
- 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/4a2cb2ff6b9790d2.
Report an issue: GitHub.