{"record":{"id":"199a8d66ff9d6bbc","repo":"mastra-ai/mastra","slug":"notification-current-id-is-missing-agentid","errorCode":null,"errorMessage":"Notification ${current.id} is missing agentId","messagePattern":"Notification (.+?) is missing agentId","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/notifications/dispatcher.ts","lineNumber":142,"sourceCode":"  });\n}\n\nasync function sendNotificationRecord({\n  mastra,\n  storage,\n  record,\n  now,\n  batchThreadState,\n}: {\n  mastra: Mastra;\n  storage: NotificationsStorage;\n  record: NotificationRecord;\n  now: Date;\n  batchThreadState?: NotificationDeliveryThreadState;\n}): Promise<{ record: NotificationRecord; signal: CreatedAgentSignal } | null> {\n  const current = await storage.getNotification({ threadId: record.threadId, id: record.id });\n  if (!current || current.status !== 'pending' || current.deliveredSignalId) return null;\n  if (!current.agentId) throw new Error(`Notification ${current.id} is missing agentId`);\n  if (!current.resourceId) throw new Error(`Notification ${current.id} is missing resourceId`);\n\n  const agent = (await mastra.getAgentById(current.agentId as never)) as NotificationDispatchAgent;\n  const threadState =\n    batchThreadState ??\n    agentThreadStreamRuntime.getThreadState(\n      { resourceId: current.resourceId, threadId: current.threadId },\n      agent.getPubSub?.(),\n    );\n  if (current.priority === 'high' && current.summarySignalId && threadState === 'active') return null;\n\n  const signal = createNotificationSignal({\n    ...current,\n    status: 'delivered',\n    deliveredAt: now,\n    lastDeliveryAttemptAt: now,\n  });\n  const streamOptions = await resolveIfIdleStreamOptions(mastra, agent, { record: current, threadState, now });","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/notifications/dispatcher.ts#L124-L160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (hand-inserted record)\nawait storage.saveNotification({ id: 'n1', threadId: 't1', resourceId: null, status: 'pending' });\n// after\nawait storage.saveNotification({ id: 'n1', threadId: 't1', agentId: 'my-agent', resourceId: 'user-1', status: 'pending' });","handlingStrategy":"try-catch","validationCode":"const rec = await storage.getNotification({ threadId, id });\nif (rec && rec.status === 'pending' && !rec.agentId) {\n  logger.warn('Skipping notification with missing agentId', { id });\n  await storage.updateNotification({ id, threadId, status: 'failed', lastDeliveryError: 'missing agentId' });\n}","typeGuard":"function isDeliverable(rec: NotificationRecord | null): rec is NotificationRecord & { agentId: string; resourceId: string } {\n  return !!rec && rec.status === 'pending' && typeof rec.agentId === 'string' && typeof rec.resourceId === 'string';\n}","tryCatchPattern":"try {\n  await dispatchNotifications(mastra, storage, records, now);\n} catch (err) {\n  if (err instanceof Error && /is missing agentId/.test(err.message)) {\n    const id = /Notification (.+) is missing agentId/.exec(err.message)?.[1];\n    logger.error('Corrupt notification record, marking failed', { id, err });\n    await storage.updateNotification({ id, threadId, status: 'failed', lastDeliveryError: err.message });\n  } else {\n    throw err;\n  }\n}","preventionTips":["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."],"tags":["notifications","storage","data-integrity"],"backgroundTag":"notification-missing-agent-id","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}