# n8n Workflow Health Check (`rashed245-owner/n8n-workflow-health-check`) Actor

Paste exported n8n workflow JSON or n8n.io template links and get a ranked defect report: missing error handling, swallowed errors, deprecated nodes, open webhooks, hard-coded secrets, missing retries/timeouts, pinned test data, dead nodes. No access to your n8n instance needed.

- **URL**: https://apify.com/rashed245-owner/n8n-workflow-health-check.md
- **Developed by:** [Rashed Alsuwaidi](https://apify.com/rashed245-owner) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Paste your exported n8n workflow JSON and get a ranked defect report in seconds: missing error handling, swallowed errors, deprecated or outdated nodes, unauthenticated webhooks, hard-coded secrets, missing retries and timeouts, pinned test data, dead nodes, broken expression references. It reads the JSON only. It never connects to your n8n instance and never asks for a credential.

**Try it before you paste anything.** Press *Start* with the input left empty and it analyses three bundled, clearly fictional sample workflows for free, so you can see exactly what a real report looks like.

### What it checks in an n8n workflow

Every rule is deterministic and runs on the exported JSON. One row per finding, worst first, with the node, what fails when it fails, the fix, and the evidence path in the JSON.

| Check | Severity | What it catches |
|---|---|---|
| `ERRORS_SWALLOWED` | high | Node set to *Continue* on error (or legacy `continueOnFail`): failures flow down the success path and the run is marked successful |
| `ERROR_OUTPUT_UNCONNECTED` | high | *Continue (using error output)* is on but nothing is connected to the error output |
| `WEBHOOK_NO_AUTH` | high | Webhook trigger with no authentication |
| `HARDCODED_SECRET` | high | API keys, bearer tokens, JWTs or password-looking literals typed into node parameters (values are masked in the report) |
| `CREDENTIAL_NOT_SET` | high | An app node (Slack, Sheets, HubSpot, Postgres, OpenAI, …) with no credential selected |
| `EXPRESSION_BROKEN_NODE_REF` | high | `$('Node name')` / `$node["…"]` pointing at a node that does not exist |
| `TRIGGER_NOT_CONNECTED`, `CONNECTION_TO_MISSING_NODE` | high | Structural breaks in the graph |
| `NO_ERROR_WORKFLOW` | medium | No Error Workflow configured, so a stopped execution notifies nobody |
| `ERROR_EXECUTIONS_NOT_SAVED` | medium | Failed executions are not saved, so failures cannot be inspected |
| `DEPRECATED_NODE` | medium | Function, FunctionItem, Start, Item Lists, Spreadsheet File, legacy OpenAI, Interval/Cron … with the current replacement named |
| `PINNED_DATA_PRESENT` | medium | Pinned test data left on nodes |
| `IF_BRANCH_UNHANDLED` | medium | IF node with one branch connected and the other dropped |
| `CREDENTIAL_UNRESOLVED` | medium | Credential referenced by name with no ID (will not resolve after import) |
| `HTTP_PLAINTEXT_URL` | medium | HTTP Request to `http://` |
| `NO_TRIGGER` | medium | Workflow that can never start on its own |
| `OUTDATED_NODE_VERSION` | low | Node still on an old major `typeVersion` |
| `NO_RETRY`, `HTTP_NO_TIMEOUT` | low | Outbound calls with no retry or no timeout |
| `HARD_CODED_INDEX` | low | Expressions like `$items()[0]` that break on empty input |
| `NODE_UNREACHABLE`, `DISABLED_NODE` | low | Leftover nodes that never run |

Each workflow also gets a **health score**: 100 − (15 × high + 6 × medium + 2 × low), floored at 0.

### Input

| Field | Type | Notes |
|---|---|---|
| `workflowJson` | array / object | One or more exported n8n workflows. A single workflow object, an array, or an object with a `workflows` array all work. Paste the whole export. |
| `templateUrls` | list of strings | Public n8n.io template links (`https://n8n.io/workflows/1234-…`) or numeric IDs. Each template is downloaded from n8n's public template API and checked before you import it. |
| `severityFloor` | `all` / `medium` / `high` | Filter the report. Default `all`. |
| `includeFixes` | boolean | Add a fix line to every finding. Default on. |
| `sampleWorkflows` | boolean | When no JSON and no links are given, analyse the bundled fictional samples. Default on. |

No credentials, no instance URL, no API key. n8n exports never contain credential values, and this Actor never asks for them.

### Output

**Dataset** — one row per finding plus one `workflow_summary` row per workflow. Fields: `kind`, `workflowName`, `workflowId`, `source` (`sample` / `json` / `template`), `sourceRef`, `checkId`, `severity`, `title`, `nodeName`, `nodeType`, `detail`, `fix`, `evidence`, `healthScore`, `nodeCount`, `findingsHigh/Medium/Low`, `billable`, `analysedAt`, `checkerVersion`. Two views are provided: *Findings* and *Workflow scores*.

**Key-value store** — `REPORT` (a Markdown report you can paste into a ticket or send to a client) and `RUN_SUMMARY` (JSON: per-workflow scores and the billed count).

Example finding row:

```json
{
  "kind": "finding",
  "workflowName": "Sample A — Lead intake to CRM (fictional)",
  "source": "sample",
  "checkId": "ERRORS_SWALLOWED",
  "severity": "high",
  "title": "Errors are swallowed (continue on regular output)",
  "nodeName": "Enrich lead",
  "nodeType": "n8n-nodes-base.httpRequest",
  "detail": "When this node fails, the error item is passed down the normal success path. Downstream nodes receive an error object instead of data and the run is marked successful. Records are lost without any signal.",
  "fix": "Set On Error to \"Continue (using error output)\" and connect the error output to a handler, or use \"Stop Workflow\" with an Error Workflow.",
  "evidence": "nodes[1].continueOnFail = true",
  "billable": false
}
```

### Pricing

**Currently free.** There is no per-workflow charge; you pay only Apify's platform usage for the run itself, which for a handful of workflows is a fraction of a cent (a three-workflow run uses about $0.0002 of compute).

Pay-per-event pricing is planned: **one `workflow-analysed` event per workflow you supply** (pasted JSON or template link), nothing else. When that switches on:

- The bundled sample workflows stay free.
- Workflows that cannot be parsed or downloaded are reported as findings and are not charged.
- Every row already carries a `billable` flag, so the dataset reconciles to an invoice one-to-one.

Worked example under that model: an agency reviewing a client's instance with 40 workflows pays 40 events; a solo builder checking one workflow before going live pays one.

### How to export a workflow from n8n

Open the workflow → menu (⋯) → **Download**. Or select all nodes on the canvas, copy, and paste the clipboard JSON directly into `workflowJson`. For a whole instance: Settings → Workflows can be exported via the n8n CLI (`n8n export:workflow --all`) and the resulting array pasted as-is.

### Use it from n8n, Make, or an AI agent

Run it through the Apify API, the Apify node in n8n, or over MCP from an agent. The dataset and the `REPORT` key-value entry are available immediately after the run finishes. Typical use: a nightly job that exports all workflows and posts the high-severity rows to Slack; or a pre-import check on any template link before it touches production.

### What it does not do

It does not connect to your n8n instance, read credential values, execute anything, or change your workflows. It does not review business logic — it finds structural defects, not wrong intentions. The deprecated-node and node-version lists are conservative: an unknown or brand-new node type is not flagged rather than guessed at.

### Reliability and proof

Reliability and run statistics on this page are computed by Apify from real run outcomes, not stated by the developer. The default input runs a real analysis on real rules every time; there is no stub path.

### Operation

This Actor is built and operated by LIFE ZERO, an AI-operated business (a UAE-licensed entity). Runs are fully automated; there is no human support channel. Issues can be reported through the Actor's Issues tab on Apify and are read by the operating system on its next cycle.

# Actor input Schema

## `workflowJson` (type: `array`):

One or more workflows as exported from n8n (Workflow menu → Download, or copy-paste from the editor). Accepts a single workflow object, an array of workflow objects, or an object with a `workflows` array. Credential values are never present in n8n exports and are never requested here.

## `templateUrls` (type: `array`):

Public n8n.io workflow template URLs (e.g. https://n8n.io/workflows/2019-...) or numeric template IDs. Each template is downloaded from n8n's public template API and analysed before you import it.

## `severityFloor` (type: `string`):

Report all findings, or only medium and above, or only high.

## `includeFixes` (type: `boolean`):

Add a concrete `fix` line to every finding.

## `sampleWorkflows` (type: `boolean`):

When you supply no workflow JSON and no template links, the Actor analyses three fictional sample workflows so you can see real output before connecting anything. Sample analyses are never charged.

## Actor input object example

```json
{
  "workflowJson": [],
  "templateUrls": [],
  "severityFloor": "all",
  "includeFixes": true,
  "sampleWorkflows": true
}
```

# Actor output Schema

## `findings` (type: `string`):

One row per defect (kind=finding) plus one row per workflow (kind=workflow\_summary), worst first. Fields are documented in the dataset schema.

## `report` (type: `string`):

Human-readable report of all findings, grouped by workflow and severity.

## `runSummary` (type: `string`):

Counts of workflows analysed and billed, severity floor used, and whether the charge limit was hit.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "workflowJson": [],
    "templateUrls": [],
    "severityFloor": "all",
    "includeFixes": true,
    "sampleWorkflows": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("rashed245-owner/n8n-workflow-health-check").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "workflowJson": [],
    "templateUrls": [],
    "severityFloor": "all",
    "includeFixes": True,
    "sampleWorkflows": True,
}

# Run the Actor and wait for it to finish
run = client.actor("rashed245-owner/n8n-workflow-health-check").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "workflowJson": [],
  "templateUrls": [],
  "severityFloor": "all",
  "includeFixes": true,
  "sampleWorkflows": true
}' |
apify call rashed245-owner/n8n-workflow-health-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rashed245-owner/n8n-workflow-health-check"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/p9alIbRdYMGmnhMKz/builds/VPgmZ5SrAnGtdEPoY/openapi.json
