mastra-ai/mastra · error

Notification summary is missing resourceId

Error message

Notification summary is missing resourceId

What it means

sendNotificationSummary builds an agent signal summarizing a batch of notification records, but it requires the first record to carry both agentId and resourceId. The resourceId identifies which resource (e.g. user/thread owner) the summary belongs to, and without it the signal cannot be routed. The library throws this error to fail fast on a malformed batch rather than dispatch an unattributable summary.

Source

Thrown at packages/core/src/notifications/dispatcher.ts:195

    lastDeliveryAttemptAt: now,
  });
  return { record: updated, signal: result.signal };
}

async function sendNotificationSummary({
  mastra,
  storage,
  records,
  now,
}: {
  mastra: Mastra;
  storage: NotificationsStorage;
  records: NotificationRecord[];
  now: Date;
}): Promise<{ records: NotificationRecord[]; signal: CreatedAgentSignal }> {
  const first = records[0];
  if (!first?.agentId) throw new Error('Notification summary is missing agentId');
  if (!first.resourceId) throw new Error('Notification summary is missing resourceId');

  const agent = (await mastra.getAgentById(first.agentId as never)) as NotificationDispatchAgent;
  const summary = summarizeNotifications(records);
  const signal = createNotificationSummarySignal(summary);
  // The all-low-priority batch persists without waking, so it never starts a
  // run and needs no stream options.
  const allLowPriority = records.every(record => record.priority === 'low');
  const streamOptions = allLowPriority
    ? undefined
    : await resolveIfIdleStreamOptions(mastra, agent, {
        record: first,
        threadState: agentThreadStreamRuntime.getThreadState(
          { resourceId: first.resourceId, threadId: first.threadId },
          agent.getPubSub?.(),
        ),
        now,
      });
  const target: SendAgentSignalOptions = allLowPriority

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure every NotificationRecord passed to sendNotificationSummary has a non-empty resourceId at creation time
  2. Verify custom storage round-trips resourceId (serialize/deserialize preserves it)
  3. Filter or repair records before batching: skip or backfill records missing resourceId
  4. Check for schema migrations that may have dropped the resourceId column/field

Example fix

// before
await storage.createNotification({ threadId, agentId: 'agent-1', summary });
// after
await storage.createNotification({ threadId, agentId: 'agent-1', resourceId: 'user-123', summary });
Defensive patterns

Strategy: validation

Validate before calling

function canSummarize(records) {
  const first = records[0];
  return Boolean(first && first.agentId && first.resourceId);
}
if (!canSummarize(records)) throw new Error('Batch missing agentId or resourceId');

Type guard

function hasResourceId(r): r is NotificationRecord & { resourceId: string } {
  return typeof r.resourceId === 'string' && r.resourceId.length > 0;
}

Try / catch

try {
  await sendNotificationSummary({ mastra, storage, records, now });
} catch (e) {
  if (e.message.includes('missing resourceId')) {
    logger.error('Notification batch missing resourceId', { recordIds: records.map(r => r.id) });
  }
}

Prevention

When it happens

Trigger: Calling mastra.getNotifications() style flows or the notification dispatcher where records[0] lacks a resourceId field — typically when notifications were created without a resourceId or the record was manually constructed/persisted by custom storage.

Common situations: Custom storage implementations that drop resourceId when persisting; creating notifications programmatically via low-level storage APIs without setting resourceId; records migrated from older schema versions before resourceId was added.

Related errors


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