AutomationFlowsAI & RAG › Log Workflow Failures with Google Gemini, Google Sheets, and Gmail Alerts

Log Workflow Failures with Google Gemini, Google Sheets, and Gmail Alerts

BySwapnil Mandloi @swapnil-mandloi on n8n.io

This error workflow captures n8n workflow failures, classifies them, generates a short Google Gemini diagnosis, logs each incident to Google Sheets, and emails an on-call address via Gmail only for critical errors. Triggers when a linked n8n workflow fails in a production…

Event trigger★★★★☆ complexityAI-powered13 nodesError TriggerChain LlmGoogle SheetsGmailGoogle Gemini Chat
AI & RAG Trigger: Event Nodes: 13 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #17451 — we link there as the canonical source.

This workflow follows the Chainllm → Gmail recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "ZSOogwAmkFCZ8KKb",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "name": "Log Workflow Failures to Google Sheets with an AI Diagnosis and Email Alert",
  "tags": [],
  "nodes": [
    {
      "id": "64419380-f4ea-44fd-9b0b-02c767a512a0",
      "name": "A Workflow Failed",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -800,
        256
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "dd6e392d-f538-4f47-98a5-c494423e2c25",
      "name": "Classify the Failure",
      "type": "n8n-nodes-base.code",
      "position": [
        -576,
        256
      ],
      "parameters": {
        "jsCode": "const src = $input.first().json;\nconst exec = src.execution || {};\nconst wf = src.workflow || {};\nconst err = exec.error || {};\n\nconst message = String(err.message || 'Unknown error');\nconst failedNode = (err.node && err.node.name) || exec.lastNodeExecuted || 'Unknown node';\nconst failedNodeType = (err.node && err.node.type) || '';\n\nlet errorType = 'Unclassified';\nlet severity = 'Critical';\n\nif (/401|403|unauthor|forbidden|invalid api key|credential/i.test(message)) {\n  errorType = 'Authentication';\n  severity = 'Critical';\n} else if (/429|rate.?limit|quota|too many requests/i.test(message)) {\n  errorType = 'Rate limit';\n  severity = 'Warning';\n} else if (/ETIMEDOUT|ECONNRESET|ECONNREFUSED|ENOTFOUND|socket hang up|timeout|502|503|504/i.test(message)) {\n  errorType = 'Transient network';\n  severity = 'Warning';\n} else if (/cannot read|is not a function|undefined|is not iterable/i.test(message)) {\n  errorType = 'Unexpected data shape';\n  severity = 'Critical';\n} else if (/required|missing|not found|does not exist/i.test(message)) {\n  errorType = 'Configuration';\n  severity = 'Critical';\n}\n\nreturn [{\n  json: {\n    failed_at: new Date().toISOString(),\n    workflow_name: wf.name || 'Unknown workflow',\n    workflow_id: wf.id || '',\n    execution_id: String(exec.id || ''),\n    execution_url: exec.url || '',\n    failed_node: failedNode,\n    failed_node_type: failedNodeType,\n    error_message: message.slice(0, 900),\n    error_type: errorType,\n    severity: severity,\n    is_retry: Boolean(exec.retryOf)\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "752a756d-d786-4208-9938-7d986466b395",
      "name": "Write Plain English Diagnosis",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "onError": "continueRegularOutput",
      "position": [
        -352,
        256
      ],
      "parameters": {
        "text": "=Workflow: {{ $json.workflow_name }}\nFailed node: {{ $json.failed_node }} ({{ $json.failed_node_type }})\nClassified as: {{ $json.error_type }}\nRaw error: {{ $json.error_message }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "You triage n8n workflow failures for an operations team. Reply in at most three short sentences. Sentence one: what actually went wrong, in plain English, no jargon. Sentence two: the single most likely cause. Sentence three: the first concrete thing the on-call person should check or click. Never invent node names or credentials that were not mentioned. If the error is genuinely ambiguous, say so instead of guessing."
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "4240e4db-6d2d-4982-81d2-3d38cfa42009",
      "name": "Build Incident Record",
      "type": "n8n-nodes-base.set",
      "position": [
        0,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "i-at",
              "name": "failed_at",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.failed_at }}"
            },
            {
              "id": "i-wfn",
              "name": "workflow_name",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.workflow_name }}"
            },
            {
              "id": "i-wfi",
              "name": "workflow_id",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.workflow_id }}"
            },
            {
              "id": "i-eid",
              "name": "execution_id",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.execution_id }}"
            },
            {
              "id": "i-eurl",
              "name": "execution_url",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.execution_url }}"
            },
            {
              "id": "i-node",
              "name": "failed_node",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.failed_node }}"
            },
            {
              "id": "i-msg",
              "name": "error_message",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.error_message }}"
            },
            {
              "id": "i-type",
              "name": "error_type",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.error_type }}"
            },
            {
              "id": "i-sev",
              "name": "severity",
              "type": "string",
              "value": "={{ $('Classify the Failure').item.json.severity }}"
            },
            {
              "id": "i-diag",
              "name": "ai_diagnosis",
              "type": "string",
              "value": "={{ $json.text || \"No diagnosis available\" }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5bb02db8-105a-4b21-a022-684efdb8f309",
      "name": "Log Incident to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        224,
        256
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "failed_at",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "failed_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "workflow_name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "workflow_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "workflow_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "workflow_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "execution_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "execution_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "execution_url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "execution_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "failed_node",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "failed_node",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "error_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_type",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "error_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "severity",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "severity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ai_diagnosis",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ai_diagnosis",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1892996817,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Av4EkjNrNbexv-2JFgFoK7atDTuXTzi5FUHKjJb6eKQ/edit#gid=1892996817",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Av4EkjNrNbexv-2JFgFoK7atDTuXTzi5FUHKjJb6eKQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Av4EkjNrNbexv-2JFgFoK7atDTuXTzi5FUHKjJb6eKQ/edit?usp=drivesdk",
          "cachedResultName": "n8n Community Leads - Swapnil AI Labs"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 2000
    },
    {
      "id": "cd047cb6-e3d9-47c4-9893-6eeedc6003dc",
      "name": "Critical Enough to Wake Someone?",
      "type": "n8n-nodes-base.if",
      "position": [
        448,
        256
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "sev-check",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Build Incident Record').item.json.severity }}",
              "rightValue": "Critical"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "30cc4161-2d54-4af3-a209-59d963fe2cd4",
      "name": "Email the On-Call Owner",
      "type": "n8n-nodes-base.gmail",
      "maxTries": 3,
      "position": [
        672,
        256
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<div style=\"font-family:Arial,sans-serif;font-size:14px;color:#222222;\"><h2 style=\"margin:0 0 12px 0;\">Workflow failure</h2><p style=\"background:#fdecea;border-left:4px solid #b00020;padding:12px;margin:0 0 16px 0;\"><strong>{{ $('Build Incident Record').item.json.ai_diagnosis }}</strong></p><table style=\"border-collapse:collapse;\"><tr><td style=\"padding:6px 14px 6px 0;color:#666666;\">Workflow</td><td style=\"padding:6px 0;\">{{ $('Build Incident Record').item.json.workflow_name }}</td></tr><tr><td style=\"padding:6px 14px 6px 0;color:#666666;\">Failed node</td><td style=\"padding:6px 0;\">{{ $('Build Incident Record').item.json.failed_node }}</td></tr><tr><td style=\"padding:6px 14px 6px 0;color:#666666;\">Category</td><td style=\"padding:6px 0;\">{{ $('Build Incident Record').item.json.error_type }}</td></tr><tr><td style=\"padding:6px 14px 6px 0;color:#666666;\">Time</td><td style=\"padding:6px 0;\">{{ $('Build Incident Record').item.json.failed_at }}</td></tr></table><p style=\"margin:16px 0 4px 0;color:#666666;\">Raw error</p><pre style=\"background:#f4f4f4;padding:12px;font-size:12px;white-space:pre-wrap;\">{{ $('Build Incident Record').item.json.error_message }}</pre><p><a href=\"{{ $('Build Incident Record').item.json.execution_url }}\" style=\"display:inline-block;background:#1a1a1a;color:#ffffff;padding:10px 18px;text-decoration:none;\">Open the failed execution</a></p></div>",
        "options": {
          "appendAttribution": false
        },
        "subject": "=[{{ $('Build Incident Record').item.json.error_type }}] {{ $('Build Incident Record').item.json.workflow_name }} failed"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.2,
      "waitBetweenTries": 2000
    },
    {
      "id": "177b44cd-ae21-4103-a9fb-cc433996c6f2",
      "name": "Overview and Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1984,
        -320
      ],
      "parameters": {
        "color": 4,
        "width": 1080,
        "height": 948,
        "content": "## Catch every workflow failure, explain it in plain English, and log it in one place\n\n**Who is this for**\nAnyone running more than a handful of n8n workflows in production. Instead of adding error handling to each workflow separately, you build this once and point every other workflow at it.\n\n**What it does**\nThis is an error workflow. It never runs on its own. When any workflow you have linked to it fails, this one starts, reads the failure payload, classifies the error, asks an AI model to explain it in three sentences an on-call person can act on, writes a row to an incident log, and emails only when the failure is genuinely critical.\n\n**How it works**\n1. The Error Trigger receives the failing workflow name, execution ID, execution URL, failed node and raw error message.\n2. A Code node matches the error text against known patterns and assigns a category and a severity. Authentication, configuration and data shape problems are Critical. Rate limits and transient network errors are Warning, because they usually clear on their own.\n3. A Basic LLM Chain converts the raw stack message into three short sentences: what broke, why it probably broke, and what to check first.\n4. A Set node assembles one clean incident record.\n5. Google Sheets appends the record, so every failure is captured whether or not anyone is emailed.\n6. The IF node sends an email only for Critical incidents. Warnings are logged silently, which is what keeps this from becoming noise you learn to ignore.\n\n**Setup**\n1. Connect your Google Gemini credential to the Diagnosis Model node.\n2. Create a Google Sheet with a tab named Incidents and these headers: failed_at, workflow_name, workflow_id, execution_id, execution_url, failed_node, error_message, error_type, severity, ai_diagnosis.\n3. Connect your Google Sheets credential and select that document.\n4. Connect your Gmail credential and replace oncall@example.com with the address that should be paged.\n5. Save and activate this workflow.\n6. Open any workflow you want covered, go to Settings, and set Error Workflow to this one. Repeat for each workflow you care about.\n7. To test it, add a temporary node that always fails to a spare workflow and run it in production mode. Error workflows do not fire on manual test runs."
      },
      "typeVersion": 1
    },
    {
      "id": "2f4f6579-3a89-41ad-b3c4-7c31eade3499",
      "name": "Section 1 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -64
      ],
      "parameters": {
        "color": 5,
        "width": 460,
        "height": 200,
        "content": "## 1. Understand the failure\nPattern matching first, so severity does not depend on the model being available."
      },
      "typeVersion": 1
    },
    {
      "id": "6d962a02-a2d5-425e-9e92-0018717cee52",
      "name": "Section 2 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        -64
      ],
      "parameters": {
        "color": 3,
        "width": 480,
        "height": 200,
        "content": "## 2. Explain it like a colleague would\nThree sentences: what broke, likely cause, first thing to check."
      },
      "typeVersion": 1
    },
    {
      "id": "554111de-55c0-4e02-96b0-c1eca9c10960",
      "name": "Section 3 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -64
      ],
      "parameters": {
        "color": 6,
        "width": 620,
        "content": "## 3. Always log, selectively alert\nEvery failure is recorded. Only Critical ones send email."
      },
      "typeVersion": 1
    },
    {
      "id": "a2aef4e8-d144-40b9-a501-ba265e51cbb1",
      "name": "Security and Safe Use",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1984,
        688
      ],
      "parameters": {
        "color": 2,
        "width": 1096,
        "height": 412,
        "content": "## Security and safe use\n\nGoogle Gemini, Google Sheets and Gmail all authenticate through the n8n credential store. Nothing is hardcoded in a node parameter.\n- Error messages can contain fragments of the data being processed, including customer records. The error text is truncated to 900 characters and is sent to the AI provider you connect. If you handle regulated data, remove the AI chain and keep the pattern based classification, which works entirely inside your instance.\n- Restrict access to the incident sheet the same way you would restrict access to your n8n execution logs. It is a record of what broke and often hints at why.\n- Severity is decided before the AI runs. If the model is down or rate limited the chain continues on error, the row is still logged and Critical failures are still emailed.\n- Only Critical incidents send email on purpose. Alerting on every transient timeout trains people to ignore the alerts.\n- Error workflows only fire on production executions, never on manual test runs. Test by triggering the covered workflow for real."
      },
      "typeVersion": 1
    },
    {
      "id": "9c6a49b8-5490-4760-acdb-8c130ea11214",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -368,
        416
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "b3d8feff-d6f5-4d35-a316-e102e73d15f8",
  "nodeGroups": [],
  "connections": {
    "A Workflow Failed": {
      "main": [
        [
          {
            "node": "Classify the Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify the Failure": {
      "main": [
        [
          {
            "node": "Write Plain English Diagnosis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Incident Record": {
      "main": [
        [
          {
            "node": "Log Incident to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Write Plain English Diagnosis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Log Incident to Google Sheets": {
      "main": [
        [
          {
            "node": "Critical Enough to Wake Someone?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Plain English Diagnosis": {
      "main": [
        [
          {
            "node": "Build Incident Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Critical Enough to Wake Someone?": {
      "main": [
        [
          {
            "node": "Email the On-Call Owner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This error workflow captures n8n workflow failures, classifies them, generates a short Google Gemini diagnosis, logs each incident to Google Sheets, and emails an on-call address via Gmail only for critical errors. Triggers when a linked n8n workflow fails in a production…

Source: https://n8n.io/workflows/17451/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Stop manually exporting CSVs and start automating your marketing insights.

Gmail, Chain Llm, Google Sheets +4
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

HTTP Request, Google Sheets, OpenRouter Chat +5
AI & RAG

This workflow runs daily to send Gemini-generated cold emails from leads stored in Google Sheets via Gmail, schedules two follow-ups based on time since sending, and continuously monitors Gmail for re

Gmail Trigger, Google Sheets, Slack +3
AI & RAG

Automate your lead intake, scoring, and outreach pipeline. This workflow collects leads from forms, enriches and scores them using Relevance AI, routes them by quality, and triggers the right follow-u

Form Trigger, HTTP Request, Chain Llm +6
AI & RAG

This is an advanced "Agentic" workflow that acts as an autonomous lead generation specialist. It goes beyond simple scraping by "thinking" about where to look for contact info. Search & Filter: It per

HTTP Request, Google Gemini Chat, Google Sheets +2