{
  "id": "6jzmhfgUEA7pHhza",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Route workflow errors from n8n to Slack and Notion",
  "tags": [],
  "nodes": [
    {
      "id": "78dc4d05-3998-4c70-b1f3-f72cd7cc5262",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        48
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Route workflow errors from n8n to Slack and Notion\n\n### How it works\n\nThis workflow catches failed n8n executions, normalizes and classifies the error, then records it as an incident in Notion. It checks whether the error matches an existing open incident, updating repeated failures or creating a new incident as needed, and sends Slack alerts only when severity and repeat rules require it. A separate scheduled branch builds and posts a daily Slack digest of open incidents from Notion.\n\n### Setup steps\n\n- Configure the n8n error workflow setting so failed workflows route to this workflow's error trigger.\n- Add Notion credentials and set the target Notion incident database ID in the template configuration node.\n- Add Slack credentials and set the Slack channel ID used for immediate alerts and daily digests.\n- Verify the Notion database has the properties expected by the create, update, query, and digest nodes, such as incident title, workflow, severity, status, occurrence count, and timestamps.\n- Set the daily digest schedule and confirm the minimum Slack severity and default incident status values match your incident process.\n\n### Customization\n\nAdjust the classification code, deduplication matching logic, Slack severity threshold, repeat-alert rules, default incident status, and daily digest schedule/message format to match your team's escalation policy."
      },
      "typeVersion": 1
    },
    {
      "id": "9b9611c7-132f-41fa-a599-6ec75567900b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 336,
        "content": "## Catch and configure errors\n\nStarts the error-handling path when another n8n workflow fails and loads template-level configuration such as Notion database, Slack channel, severity threshold, and default incident status."
      },
      "typeVersion": 1
    },
    {
      "id": "53d00312-6f02-4cd9-aa80-2c4bd4f6c07d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        400
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 304,
        "content": "## Normalize incident details\n\nCleans the raw error payload, classifies the failure, and builds a structured incident object for downstream Notion lookup and alerting decisions."
      },
      "typeVersion": 1
    },
    {
      "id": "0318a2a3-827f-4aed-8868-e1b82b0f985a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 336,
        "content": "## Find matching incident\n\nQueries Notion for an existing matching incident and branches the workflow depending on whether the failure should update an open incident or create a new one."
      },
      "typeVersion": 1
    },
    {
      "id": "06e9a3e3-f6ea-4e85-9b65-d0c7e02775b5",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 320,
        "content": "## Update existing incident\n\nPrepares the update payload for a repeated error and writes the updated occurrence details back to the existing Notion incident."
      },
      "typeVersion": 1
    },
    {
      "id": "83f9a3b4-8014-4a98-8f0e-792f80578bc7",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2688,
        48
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 576,
        "content": "## Handle repeated alerts\n\nDecides whether an updated recurring incident should notify Slack, then either sends the repeated-incident alert or intentionally skips notification."
      },
      "typeVersion": 1
    },
    {
      "id": "6d8689ed-d053-4d0d-99d4-8a7f6cf3fb21",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        608
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 336,
        "content": "## Create new incident\n\nCreates a new Notion incident for previously unseen errors and checks whether the new incident meets the criteria for an immediate Slack notification."
      },
      "typeVersion": 1
    },
    {
      "id": "dcf586cb-b1be-4f32-952d-866a37444dcb",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2688,
        656
      ],
      "parameters": {
        "color": 7,
        "height": 624,
        "content": "## Handle new alerts\n\nCompletes the new-incident branch by either sending a Slack alert for qualifying incidents or skipping notification for lower-priority cases."
      },
      "typeVersion": 1
    },
    {
      "id": "095495a1-54bb-4fb3-9256-9f1bf633792c",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        1200
      ],
      "parameters": {
        "color": 7,
        "width": 912,
        "height": 304,
        "content": "## Build daily digest\n\nRuns on a schedule, retrieves open incidents from Notion, builds the digest message, and checks whether there is anything worth sending."
      },
      "typeVersion": 1
    },
    {
      "id": "232c45ea-7798-4cdb-b574-4085f0317c15",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        1008
      ],
      "parameters": {
        "color": 7,
        "height": 368,
        "content": "## Send daily digest\n\nPosts the prepared daily summary of open incidents to Slack when the digest branch determines a message is needed."
      },
      "typeVersion": 1
    },
    {
      "id": "8c8ca81f-956f-46d9-9290-c1b9bd813c33",
      "name": "When Workflow Error Occurs",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        576,
        528
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2179e55f-02bf-4f58-a75c-97cf47be1660",
      "name": "Set Error Notification Config",
      "type": "n8n-nodes-base.set",
      "position": [
        816,
        528
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e20fca62-f73a-4cb2-95be-adfa01cb7afb",
              "name": "notion_database_id",
              "type": "string",
              "value": "YOUR_NOTION_DATABASE_ID_HERE"
            },
            {
              "id": "f4fa6d6c-4fa8-4a50-96ba-091043fa57f4",
              "name": "slack_channel_id",
              "type": "string",
              "value": "YOUR_SLACK_CHANNEL_ID_HERE"
            },
            {
              "id": "e4e66ce9-9da5-4377-bcc7-41de4bb02811",
              "name": "minimum_slack_severity",
              "type": "string",
              "value": "High"
            },
            {
              "id": "d7452306-b214-4d20-971e-e7221d26a036",
              "name": "default_incident_status",
              "type": "string",
              "value": "Open"
            },
            {
              "id": "bbb81950-b031-4f42-bf08-7493fe68c61a",
              "name": "resolved_incident_status",
              "type": "string",
              "value": "Resolved"
            },
            {
              "id": "08d0048d-9a08-4da8-b3d4-6c4b8413ca32",
              "name": "template_owner_note",
              "type": "string",
              "value": "Replace placeholders before production use. Do not hardcode API keys, channel IDs, database IDs, execution URLs, or personal data inside workflow nodes."
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "f6d1699f-fc99-446c-b4d1-f4ed0d43384c",
      "name": "Clean Error Details",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        528
      ],
      "parameters": {
        "jsCode": "const input = $input.first().json;\n\nconst execution = input.execution || {};\nconst workflow = input.workflow || {};\nconst trigger = input.trigger || {};\nconst error = execution.error || trigger.error || input.error || {};\n\nconst errorMessage = error.message || input.message || 'Unknown error message';\nconst errorStack = error.stack || '';\nconst lastNodeExecuted =\n\texecution.lastNodeExecuted ||\n\ttrigger.name ||\n\tinput.lastNodeExecuted ||\n\t'Unknown node';\n\nconst workflowName = workflow.name || input.workflowName || 'Unknown workflow';\nconst workflowId = workflow.id || input.workflowId || 'unknown-workflow-id';\n\nconst executionId = execution.id || 'not-saved';\nconst executionUrl = execution.url || null;\nconst retryOf = execution.retryOf || '';\nconst mode = execution.mode || trigger.mode || 'unknown';\n\nconst timestamp = new Date().toISOString();\n\nreturn [\n\t{\n\t\tjson: {\n\t\t\tworkflow_name: workflowName,\n\t\t\tworkflow_id: workflowId,\n\t\t\texecution_id: executionId,\n\t\t\texecution_url: executionUrl,\n\t\t\tretry_of: retryOf,\n\t\t\terror_node: lastNodeExecuted,\n\t\t\terror_message: errorMessage,\n\t\t\terror_stack: errorStack,\n\t\t\texecution_mode: mode,\n\t\t\terror_timestamp: timestamp,\n\n\t\t\tnotion_database_id: input.notion_database_id,\n\t\t\tslack_channel_id: input.slack_channel_id,\n\t\t\tminimum_slack_severity: input.minimum_slack_severity,\n\t\t\tdefault_incident_status: input.default_incident_status,\n\t\t\tresolved_incident_status: input.resolved_incident_status,\n\t\t\ttemplate_owner_note: input.template_owner_note,\n\t\t},\n\t},\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "5a397e84-d3f4-4c05-8bc0-ec0df5ccbd77",
      "name": "Classify Error Severity",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        528
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\n\nconst text = [\n\titem.error_message || '',\n\titem.error_stack || '',\n\titem.error_node || '',\n\titem.workflow_name || '',\n].join(' ').toLowerCase();\n\nlet errorCategory = 'Unknown error';\nlet severity = 'Medium';\nlet suggestedFix = 'Review the failed execution, inspect the node input/output, and check recent workflow changes.';\n\nif (/401|403|unauthorized|forbidden|invalid credential|credential|oauth|token|api key|authentication/.test(text)) {\n\terrorCategory = 'Credential/auth error';\n\tseverity = 'High';\n\tsuggestedFix = 'Check the credential used by the failed node. Refresh OAuth credentials, verify API keys, and confirm the app connection still has permission.';\n} else if (/429|rate limit|quota|too many requests|usage limit/.test(text)) {\n\terrorCategory = 'API rate limit';\n\tseverity = 'High';\n\tsuggestedFix = 'Check API rate limits, reduce execution frequency, add wait/retry logic, or upgrade the API plan if usage is legitimate.';\n} else if (/timeout|etimedout|econnreset|network|socket hang up|dns|enotfound/.test(text)) {\n\terrorCategory = 'Timeout/network error';\n\tseverity = 'Medium';\n\tsuggestedFix = 'Check the external service status, increase timeout settings if available, and add retry logic for unstable API calls.';\n} else if (/undefined|null|cannot read|missing|required field|no data|empty|not found/.test(text)) {\n\terrorCategory = 'Missing data';\n\tseverity = 'Medium';\n\tsuggestedFix = 'Inspect the previous node output. Add IF checks or default values before this node to handle missing fields safely.';\n} else if (/400|bad request|validation|invalid parameter|invalid request/.test(text)) {\n\terrorCategory = 'Bad request';\n\tseverity = 'Medium';\n\tsuggestedFix = 'Check the request body, required fields, data types, and endpoint documentation for the failed API call.';\n} else if (/500|502|503|504|server error|service unavailable|bad gateway/.test(text)) {\n\terrorCategory = 'Server/API failure';\n\tseverity = 'High';\n\tsuggestedFix = 'The external service may be down or unstable. Check service status and add retry/backoff handling.';\n} else if (/syntaxerror|referenceerror|typeerror|expression|code node|function/.test(text)) {\n\terrorCategory = 'Expression/code error';\n\tseverity = 'Medium';\n\tsuggestedFix = 'Check expressions and Code node logic. Verify node names, field paths, and returned item structure.';\n}\n\nif (/payment|invoice|customer|production|order|webhook/.test(text) && severity === 'Medium') {\n\tseverity = 'High';\n}\n\nif (/critical|security|data loss|failed payment|refund|blocked/.test(text)) {\n\tseverity = 'Critical';\n}\n\nreturn [\n\t{\n\t\tjson: {\n\t\t\t...item,\n\t\t\terror_category: errorCategory,\n\t\t\tseverity,\n\t\t\tsuggested_fix: suggestedFix,\n\t\t},\n\t},\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "373f8de0-e42c-42fe-813a-df5a7293312a",
      "name": "Build Incident Info",
      "type": "n8n-nodes-base.code",
      "position": [
        1536,
        528
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\n\nconst cleanMessage = String(item.error_message || 'Unknown error')\n\t.replace(/\\s+/g, ' ')\n\t.trim();\n\nconst shortMessage = cleanMessage.slice(0, 140);\n\nconst fingerprint = [\n\titem.workflow_id,\n\titem.error_node,\n\titem.error_category,\n\tcleanMessage.slice(0, 120),\n]\n\t.join('|')\n\t.toLowerCase()\n\t.replace(/\\s+/g, ' ')\n\t.trim();\n\nconst incidentTitle = `[${item.severity}] ${item.workflow_name} failed at ${item.error_node}`;\n\nconst slackMessage =\n`\ud83d\udea8 *n8n workflow error detected*\n\n*Severity:* ${item.severity}\n*Category:* ${item.error_category}\n*Workflow:* ${item.workflow_name}\n*Failed node:* ${item.error_node}\n*Execution ID:* ${item.execution_id}\n\n*Error message:*\n${shortMessage}\n\n*Suggested fix:*\n${item.suggested_fix}\n\n${item.execution_url ? `*Execution URL:* ${item.execution_url}` : '*Execution URL:* Not available'}`;\n\nreturn [\n\t{\n\t\tjson: {\n\t\t\t...item,\n\t\t\tfingerprint,\n\t\t\tincident_title: incidentTitle,\n\t\t\tshort_error_message: shortMessage,\n\t\t\tslack_message: slackMessage,\n\t\t\tfirst_seen: item.error_timestamp,\n\t\t\tlast_seen: item.error_timestamp,\n\t\t\toccurrences: 1,\n\t\t},\n\t},\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "826a995f-ae6b-4d56-b78b-4dd4023bb91a",
      "name": "Search Existing Incidents",
      "type": "n8n-nodes-base.notion",
      "position": [
        1776,
        528
      ],
      "parameters": {
        "limit": 1,
        "filters": {
          "conditions": [
            {
              "key": "Fingerprint|rich_text",
              "condition": "equals",
              "richTextValue": "={{ $json.fingerprint }}"
            }
          ]
        },
        "options": {},
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Error Notification Config').first().json.notion_database_id }}"
        },
        "filterType": "manual"
      },
      "typeVersion": 2.2,
      "alwaysOutputData": true
    },
    {
      "id": "d03c88c4-0654-4e71-abd2-7d28032efdfe",
      "name": "Check Incident Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        2016,
        528
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "985950ed-c191-4b1d-838a-b099865c2d18",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "9a3fe75a-b81e-4ae5-9eb3-ecb7031005fc",
      "name": "Prepare Incident Update",
      "type": "n8n-nodes-base.code",
      "position": [
        2256,
        352
      ],
      "parameters": {
        "jsCode": "const existing = $input.first().json;\nconst incident = $('Build Incident Info').first().json;\n\nlet currentOccurrences = 1;\n\nif (existing.properties?.Occurrences?.number !== undefined) {\n\tcurrentOccurrences = existing.properties.Occurrences.number;\n} else if (existing.Occurrences !== undefined) {\n\tcurrentOccurrences = Number(existing.Occurrences) || 1;\n}\n\nconst newOccurrences = currentOccurrences + 1;\n\nreturn [\n\t{\n\t\tjson: {\n\t\t\t...incident,\n\t\t\tnotion_page_id: existing.id,\n\t\t\toccurrences: newOccurrences,\n\t\t\tis_new_incident: false,\n\t\t},\n\t},\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "309ac0dc-ec79-476b-8d72-2a55243186ac",
      "name": "Update Incident in Notion",
      "type": "n8n-nodes-base.notion",
      "position": [
        2496,
        352
      ],
      "parameters": {
        "pageId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.notion_page_id }}"
        },
        "options": {},
        "resource": "databasePage",
        "operation": "update",
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Last Seen|date",
              "date": "={{ $json.last_seen }}"
            },
            {
              "key": "Occurrences|number",
              "numberValue": "={{ $json.occurrences }}"
            },
            {
              "key": "Error Message|rich_text",
              "textContent": "={{ $json.error_message }}"
            },
            {
              "key": "Suggested Fix|rich_text",
              "textContent": "={{ $json.suggested_fix }}"
            },
            {
              "key": "Severity|select",
              "selectValue": "={{ $json.severity }}"
            },
            {
              "key": "Status|select",
              "selectValue": "={{ $('Set Error Notification Config').first().json.default_incident_status }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "14fd3711-3026-4866-923e-42016a738bb2",
      "name": "Check for New Alert",
      "type": "n8n-nodes-base.if",
      "position": [
        2496,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b18e7958-0170-4e89-a9e3-85fcc277db72",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ ({ Low: 1, Medium: 2, High: 3, Critical: 4 }[$('Build Incident Info').first().json.severity] || 0) >= ({ Low: 1, Medium: 2, High: 3, Critical: 4 }[$('Set Error Notification Config').first().json.minimum_slack_severity] || 3) }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "32ab7c3a-f826-4aff-b4cb-d303d17388f8",
      "name": "Create New Incident",
      "type": "n8n-nodes-base.notion",
      "position": [
        2256,
        800
      ],
      "parameters": {
        "title": "={{ $('Build Incident Info').first().json.incident_title }}",
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Error Notification Config').first().json.notion_database_id }}"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Incident|title",
              "title": "={{ $('Build Incident Info').first().json.incident_title }}"
            },
            {
              "key": "Fingerprint|rich_text",
              "textContent": "={{ $('Build Incident Info').first().json.fingerprint }}"
            },
            {
              "key": "Workflow Name|rich_text",
              "textContent": "={{ $('Build Incident Info').first().json.workflow_name }}"
            },
            {
              "key": "Workflow ID|rich_text",
              "textContent": "={{ String($('Build Incident Info').first().json.workflow_id || '') }}"
            },
            {
              "key": "Execution ID|rich_text",
              "textContent": "={{ String($('Build Incident Info').first().json.execution_id || '') }}"
            },
            {
              "key": "Execution URL|url",
              "urlValue": "={{ $('Build Incident Info').first().json.execution_url || null }}"
            },
            {
              "key": "Error Node|rich_text",
              "textContent": "={{ $('Build Incident Info').first().json.error_node }}"
            },
            {
              "key": "Error Category|select",
              "selectValue": "={{ $('Build Incident Info').first().json.error_category }}"
            },
            {
              "key": "Severity|select",
              "selectValue": "={{ $('Build Incident Info').first().json.severity }}"
            },
            {
              "key": "Status|select",
              "selectValue": "={{ $('Set Error Notification Config').first().json.default_incident_status }}"
            },
            {
              "key": "First Seen|date",
              "date": "={{ $('Build Incident Info').first().json.first_seen }}"
            },
            {
              "key": "Last Seen|date",
              "date": "={{ $('Build Incident Info').first().json.last_seen }}"
            },
            {
              "key": "Occurrences|number",
              "numberValue": "={{ $('Build Incident Info').first().json.occurrences }}"
            },
            {
              "key": "Error Message|rich_text",
              "textContent": "={{ $('Build Incident Info').first().json.error_message }}"
            },
            {
              "key": "Suggested Fix|rich_text",
              "textContent": "={{ $('Build Incident Info').first().json.suggested_fix }}"
            },
            {
              "key": "Slack Alert Sent|checkbox",
              "checkboxValue": "={{ ({ Low: 1, Medium: 2, High: 3, Critical: 4 }[$('Build Incident Info').first().json.severity] || 0) >= ({ Low: 1, Medium: 2, High: 3, Critical: 4 }[$('Set Error Notification Config').first().json.minimum_slack_severity] || 3) }}"
            },
            {
              "key": "Retry Of|rich_text",
              "textContent": "={{ String($('Build Incident Info').first().json.retry_of || '') }}"
            },
            {
              "key": "Mode|rich_text",
              "textContent": "={{ $('Build Incident Info').first().json.execution_mode }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ef752131-a03b-430e-96b7-79805319df9b",
      "name": "Post New Alert to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        2736,
        880
      ],
      "parameters": {
        "text": "={{ $('Build Incident Info').first().json.slack_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Error Notification Config').first().json.slack_channel_id }}"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.5
    },
    {
      "id": "88c198dc-c161-4fba-af2f-8c42f0391d34",
      "name": "Skip New Alert Notification",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2736,
        1120
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b6ae8e39-2675-497b-a9fd-b63f82e22e70",
      "name": "When Daily Digest Starts",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        576,
        1328
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "309ec89c-c028-4606-bcab-de59f3226401",
      "name": "Retrieve Open Incidents",
      "type": "n8n-nodes-base.notion",
      "position": [
        816,
        1328
      ],
      "parameters": {
        "limit": 20,
        "filters": {
          "conditions": [
            {
              "key": "Status|select",
              "condition": "does_not_equal",
              "selectValue": "={{ $('Set Error Notification Config').first().json.resolved_incident_status }}"
            }
          ]
        },
        "options": {},
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Error Notification Config').first().json.notion_database_id }}"
        },
        "filterType": "manual"
      },
      "typeVersion": 2.2
    },
    {
      "id": "4a9b8488-8f3f-4003-9090-937da85ed099",
      "name": "Craft Digest Message",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        1328
      ],
      "parameters": {
        "jsCode": "const items = $input.all().map(item => item.json).filter(item => item.id);\n\nif (items.length === 0) {\n\treturn [\n\t\t{\n\t\t\tjson: {\n\t\t\t\tsend_digest: false,\n\t\t\t\tdigest_message: 'No open n8n incidents found.',\n\t\t\t},\n\t\t},\n\t];\n}\n\nconst severityCounts = {\n\tCritical: 0,\n\tHigh: 0,\n\tMedium: 0,\n\tLow: 0,\n\tUnknown: 0,\n};\n\nconst lines = [];\n\nfor (const item of items.slice(0, 10)) {\n\tconst props = item.properties || {};\n\n\tconst title =\n\t\tprops.Incident?.title?.[0]?.plain_text ||\n\t\titem.Incident ||\n\t\t'Untitled incident';\n\n\tconst severity =\n\t\tprops.Severity?.select?.name ||\n\t\titem.Severity ||\n\t\t'Unknown';\n\n\tconst occurrences =\n\t\tprops.Occurrences?.number ||\n\t\titem.Occurrences ||\n\t\t1;\n\n\tif (severityCounts[severity] !== undefined) {\n\t\tseverityCounts[severity]++;\n\t} else {\n\t\tseverityCounts.Unknown++;\n\t}\n\n\tlines.push(`\u2022 [${severity}] ${title} \u2014 ${occurrences} occurrence(s)`);\n}\n\nconst digestMessage =\n`\ud83d\udcca *Daily n8n error digest*\n\n*Open incidents:* ${items.length}\n\n*Severity breakdown:*\nCritical: ${severityCounts.Critical}\nHigh: ${severityCounts.High}\nMedium: ${severityCounts.Medium}\nLow: ${severityCounts.Low}\n\n*Top incidents:*\n${lines.join('\\n')}\n\nReview Notion for full incident details.`;\n\nreturn [\n\t{\n\t\tjson: {\n\t\t\tsend_digest: true,\n\t\t\tdigest_message: digestMessage,\n\t\t},\n\t},\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "2ee184ba-5ee4-40ef-8c37-42e7a508e173",
      "name": "Check Digest Transmission",
      "type": "n8n-nodes-base.if",
      "position": [
        1296,
        1328
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e1037e35-35ff-479f-a21a-9fc5a1747c8c",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.send_digest }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "a54dec72-dc46-46bc-9d6b-bc2f9959f498",
      "name": "Deliver Daily Digest to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1536,
        1216
      ],
      "parameters": {
        "text": "={{ $json.digest_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Error Notification Config').first().json.slack_channel_id }}"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.5
    },
    {
      "id": "534436b9-93fa-4026-9a03-4e00422b2967",
      "name": "Evaluate Repeated Alert Necessity",
      "type": "n8n-nodes-base.if",
      "position": [
        2736,
        352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2ec4dac0-e622-4d9e-9ee9-0d6c0e7af6d0",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ ({ Low: 1, Medium: 2, High: 3, Critical: 4 }[$('Build Incident Info').first().json.severity] || 0) >= ({ Low: 1, Medium: 2, High: 3, Critical: 4 }[$('Set Error Notification Config').first().json.minimum_slack_severity] || 3) }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f88a5151-2c1b-475f-904f-a3d26e641039",
      "name": "Post Repeated Alert to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        2976,
        240
      ],
      "parameters": {
        "text": "={{ $('Build Incident Info').first().json.slack_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Error Notification Config').first().json.slack_channel_id }}"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.5
    },
    {
      "id": "e7710d98-c211-4e27-8f1d-020170dda1eb",
      "name": "Skip Repeated Alert Notification",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2976,
        480
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "9a2c1c40-1f26-433c-a99e-aa85128ca4f5",
  "nodeGroups": [],
  "connections": {
    "Build Incident Info": {
      "main": [
        [
          {
            "node": "Search Existing Incidents",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for New Alert": {
      "main": [
        [
          {
            "node": "Post New Alert to Slack",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip New Alert Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean Error Details": {
      "main": [
        [
          {
            "node": "Classify Error Severity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create New Incident": {
      "main": [
        [
          {
            "node": "Check for New Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Craft Digest Message": {
      "main": [
        [
          {
            "node": "Check Digest Transmission",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Incident Exists": {
      "main": [
        [
          {
            "node": "Prepare Incident Update",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create New Incident",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Error Severity": {
      "main": [
        [
          {
            "node": "Build Incident Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Incident Update": {
      "main": [
        [
          {
            "node": "Update Incident in Notion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve Open Incidents": {
      "main": [
        [
          {
            "node": "Craft Digest Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Daily Digest Starts": {
      "main": [
        [
          {
            "node": "Retrieve Open Incidents",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Digest Transmission": {
      "main": [
        [
          {
            "node": "Deliver Daily Digest to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Existing Incidents": {
      "main": [
        [
          {
            "node": "Check Incident Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Incident in Notion": {
      "main": [
        [
          {
            "node": "Evaluate Repeated Alert Necessity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Workflow Error Occurs": {
      "main": [
        [
          {
            "node": "Set Error Notification Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Error Notification Config": {
      "main": [
        [
          {
            "node": "Clean Error Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Repeated Alert Necessity": {
      "main": [
        [
          {
            "node": "Post Repeated Alert to Slack",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip Repeated Alert Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}