On this page
Zero errors is not the same as healthy. A schedule can stop firing, a webhook lane can lose its upstream feed, a mail poller can stick on an old cursor — and the execution log stays green the whole time, because nothing threw. Episode 08 is a workflow built to answer a sharper question than "has it run recently": has a lane missed something it actually owed.
This workflow reads the estate's own workflow list, masks every real workflow name into a pseudonymous reference before anything is stored, and checks each lane against its own expectation row in an n8n Data Table — how often it should run, and what kind of lane it is: scheduled, event-driven, upstream-count, or manual-run. Silence only becomes an incident when a lane's own obligation was missed, never from elapsed time alone.
If iframes are blocked where you are reading this, the video is at the Episode 08 video.
lane_ref before anything is stored, logged, or shown on screen.
The lane that trips in this recording did so against a threshold we set on
purpose for the demo, not a real service-level breach. The optional Slack
alert ships disabled, so the only write this run makes is a Postgres row.
What does the watchdog actually do?
A poll lists the estate's active workflows, and a masking step hashes every
real name into a lane_ref before anything downstream can see it.
Each lane is checked against an expectation row: a scheduled lane trips when
its interval elapses with no run; an event-driven lane never trips on elapsed
time alone, only on a missed upstream arrival; a manual-run lane gets a
reminder row, never an incident. An open incident sends one reminder per
cooldown window and closes itself the moment the lane recovers. The only
writes are a Postgres row and, optionally, a Slack message — the Slack node
ships disabled, so the shipped default runs in dry run.
Why elapsed time alone is the wrong question
Three kinds of quiet are healthy: a lane with no saved successes yet cannot be measured and should say so rather than claim silence off an absent number; a demand-driven lane with zero upstream arrivals has nothing to have run, and zero is correct, not silent; a lane switched off on purpose is a decision, not a failure. A monitor that cannot tell these apart from a genuine miss cries wolf until someone mutes it — and that is exactly when a real silence goes unseen too. This workflow encodes all three as explicit branches, not an afterthought bolted onto a single elapsed-time check.
What did the recorded run actually show?
A manual run against three configured lanes produced one open incident and one recovered lane, out of 63 lanes evaluated overall. One event-driven lane sat at zero upstream arrivals over the window and was correctly left alone — the exact false-alarm story a naive elapsed-time watchdog would have flagged. A second, scheduled lane was set to a 60-minute test threshold on purpose for this recording and correctly tripped an incident when it went well past that window.
| Metric | Observed |
|---|---|
| Lanes evaluated | 63 |
| Lanes missed | 1 (scheduled, test threshold, 60 minutes) |
| Incidents opened | 1 |
| Incidents recovered | 1 (event-driven lane, correctly left quiet) |
| False alarms | 0 |
| Slack messages sent | 0 — the Slack node ships disabled |
An honesty note on the history behind this build: an earlier figure attached to the original watchdog incident that inspired this workflow does not reconcile against current execution history on this instance — the largest gap visible in the data is roughly three days, and the lane in question is itself demand-driven, the same doctrine this episode teaches. We carry no retired figure forward here; the card states only what the current data supports.
The cap sheet
Gotchas worth knowing before you fork this
The workflow calls its own n8n instance's API to list active workflows, and that pull returns full workflow bodies, including every node's parameters — this is exactly why masking is the very next node, and nothing upstream of it is ever written to Postgres or rendered on screen. A whitelist gate reads the write's own action before it can reach Postgres and refuses anything outside a fixed set of shapes; a fabricated write outside that set was tested directly against the gate and it refused.
An event-driven lane needs an upstream-count window, not just a last-run timestamp — treating zero runs alone as silence is the exact false alarm this workflow exists to avoid. And a manual-run lane never opens an incident by construction; the only outcome an overdue manual-run lane can produce is a reminder row.
How do I import it and where are the swap points?
The free workflow JSON is MIT-licensed at github.com/waseemnasir2k26/n8n-workflows/tree/main/workflows/08-silent-lane-watchdog. Create the two Data Tables (the expectation row per lane and the cap sheet), run the schema against your own Postgres, import the workflow and its error workflow, and point the estate-list call at your own n8n base URL before running the manual test path.
Swap points built into the canvas on purpose:
- The schedule trigger, shipped disabled — a real 6-hour cadence swaps in once you enable it; the recorded run used one manual execution.
- The Slack alert node, shipped disabled — the workflow's only optional write beyond the incident row itself.
- The expectation row per lane, which you own — add a row for every lane you want watched, with its own kind and interval.
Frequently asked questions
What separates this from a plain "hasn't run in X minutes" alert?
An overdue-only alert would have flagged the genuinely quiet, event-driven lane in this run's own data. This workflow reads a kind column on every lane's expectation row instead, and only a scheduled lane trips on elapsed time alone; an event-driven lane trips only on a missed upstream arrival.
Does this workflow send anything on its own?
The only writes it can make are a Postgres incident row and an optional Slack message, which ships disabled by default. There is no path from this workflow to a client-facing send of any kind.
Is workflow or client data exposed anywhere?
No. Every real workflow name is hashed into a pseudonymous lane reference in the node right after the estate pull, before anything is stored, logged, or shown on screen.
What happens once an incident opens?
It sends one reminder per cooldown window and closes itself automatically the moment the lane's own obligation is met again — no human has to remember to close it by hand.
The rest of the series
One workflow per video, the JSON given away under an MIT license each time, built by Waseem Nasir at SkynetLabs.
- Episode 05, n8n clinic WhatsApp booking agent: a code guard hands off medical and price questions before the model.
- Episode 06, n8n Meta ads circuit breaker: our own breaker missed our own overspend, and this one closed the gap.
- Episode 07, n8n shared inbox router: rules sort the mail before any model reads it, drafts only.
Want your own workflow list watched for missed obligations, not just errors? Book a discovery call with SkynetLabs.
WhatsApp +92 300 1001957 · Waseem Nasir, SkynetLabs
Hire SkynetLabs, our Top Rated agency on Fiverr: https://www.fiverr.com/agencies/skynetjoellc