{"record":{"id":"4d643c5c7e358171","repo":"Budibase/budibase","slug":"notification-doc-notificationdocid-not-found","errorCode":null,"errorMessage":"Notification doc ${notificationDocId} not found","messagePattern":"Notification doc (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/sdk/workspace/escalations.ts","lineNumber":171,"sourceCode":"export async function respond(\n  escalationId: string,\n  notificationDocId: string,\n  response: EscalationResponse,\n  resolve: (escalationId: string, response: EscalationResponse) => Promise<void>\n): Promise<EscalationRespondResult> {\n  const db = context.getWorkspaceDB()\n\n  const contextDoc = await getContextDoc(escalationId)\n  if (!contextDoc) {\n    throw new Error(`Escalation ${escalationId} not found`)\n  }\n  if (contextDoc.resolution !== \"pending\") {\n    return { status: \"closed\" }\n  }\n\n  const notifDoc = await db.tryGet<EscalationNotificationDoc>(notificationDocId)\n  if (!notifDoc) {\n    throw new Error(`Notification doc ${notificationDocId} not found`)\n  }\n  // Ensure the notification actually belongs to this escalation - stops a forged\n  // payload pairing a valid notificationDocId with a different escalationId.\n  if (notifDoc.escalationId !== escalationId) {\n    console.warn(\n      \"Escalation respond: notification does not belong to escalation (possible forged payload)\",\n      {\n        escalationId,\n        notificationDocId,\n        notifEscalationId: notifDoc.escalationId,\n      }\n    )\n    throw new Error(\n      `Notification ${notificationDocId} does not belong to escalation ${escalationId}`\n    )\n  }\n  await db.put({\n    ...notifDoc,","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/escalations.ts#L153-L189","documentation":"Thrown by the escalation respond flow when the referenced notification document does not exist in the workspace DB. The escalation itself is pending, but the notification that carried the response request cannot be found, so the response is rejected rather than applied to an unverifiable notification.","triggerScenarios":"Calling respond with a notificationDocId that is absent from the DB: the notification was deleted, the ID is mistyped, or the call is made against a different workspace DB than the one containing the notification.","commonSituations":"Replaying an old notification webhook after cleanup jobs removed the doc; environment mismatches where notifications live in a tenant-specific DB; copy-paste errors between notification and escalation IDs.","solutions":["Confirm the notificationDocId matches the doc generated when the escalation notification was created","Run the respond call within the workspace context that owns the notification","If the notification was intentionally removed, treat the escalation via its context doc or re-issue a new notification"],"exampleFix":"// before\nawait respond(escalationId, response, resolve) // notificationDocId captured from an expired payload\n// after\nconst notif = await db.tryGet<EscalationNotificationDoc>(notificationDocId)\nif (notif) await respond(escalationId, response, resolve)","handlingStrategy":"validation","validationCode":"const notif = await db.tryGet<EscalationNotificationDoc>(notificationDocId)\nif (!notif) throw new Error(`Notification ${notificationDocId} not found — cannot respond`)","typeGuard":null,"tryCatchPattern":"try {\n  await respond(escalationId, response, resolve)\n} catch (err) {\n  if (/Notification .* not found/.test(err.message)) {\n    return { status: \"notification-missing\" }\n  }\n  throw err\n}","preventionTips":["Persist the escalationId/notificationDocId pair together from the original notification","Never reconstruct notification IDs from partial data","Verify tenant/workspace context so lookups hit the correct DB"],"tags":["escalations","notifications","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}