Open-sourced: three n8n sub-workflows for agent reliability — RetryClassifier, ContextBudget, PermissionGate [MIT, free]

Four days ago our production n8n stack silently dropped leads for 27 hours. The SQLite layer underneath n8n failed. The /healthz endpoint returned 200 the entire time. Four webhook callers had .catch(() => {}). Zero log lines. Zero alerts. We found out when a prospect mentioned they’d submitted a form two days earlier and never heard back. That incident forced us to ask: what actually happens in our agent workflows when something fails? For most of them, the answer was “nothing you’d ever notice.”

We audited every workflow. The results were predictable in hindsight:

  • 14 had no error handling whatsoever
  • 8 had retry logic that treated a 429 rate limit identically to a 401 auth failure
  • All of them would silently die on a large tool output (50KB+ web scrape, big DB dump)
  • None had any permission layer — agents had full access to every connected tool, always

So we built what we needed. Then open-sourced it.


AgentGuard — three importable sub-workflows, MIT, zero dependencies:

RetryClassifier — 10-class error taxonomy with specific recovery per class:

Error Class Recovery Strategy
429 Rate Limit Parse Retry-After header → wait exact duration
529 Server Overload Track consecutive → switch model after 3
400 Context Overflow Trigger compaction → retry
401/403 Auth Failure Refresh token → retry once only
Network Error Disable keep-alive → fresh connection
Quota Exceeded Permanent model downgrade
Streaming Stall Abort → retry non-streaming
Input Validation Log + fail (no retry — fix the input)

Backoff: min(500ms × 2^attempt, 32s) + jitter. When your primary API is down, cascades to local Ollama at $0/call.

ContextBudget — two-tier compaction for agent loops:

Two ways context windows die silently: (1) one large tool result consumes the whole window in a single turn, (2) 20 turns of accumulated history exhausts it.

  • Tier 1: truncate oversized tool results to head+tail preview + file reference. Free, runs every turn.
  • Tier 2: summarize old turns with cheapest available model (~$0.001). Fires only when needed.
  • Circuit breaker prevents infinite compaction loops.

PermissionGate — glob-pattern allow/deny on every tool call before execution:

{ "tool": "bash", "pattern": "rm -rf*", "action": "deny" }
{ "tool": "bash", "pattern": "ls *", "action": "allow" }
{ "tool": "database", "pattern": "DROP ", "action": "deny" }
{ "tool": "git", "pattern": "push", "action": "prompt" }

Three modes: allow (execute + log), deny (block + return error to model), prompt (hold + notify operator + wait for approval). Every decision logged to PostgreSQL, webhook, or file.


How to use:

  1. Download workflow JSONs from GitHub
  2. Import into n8n (Settings → Import Workflow)
  3. Add Execute Workflow node in your agent workflow
  4. Configure (fallback model, context threshold, permission rules)

Each component is standalone — use one, two, or all three. Works with any LLM provider. n8n 1.70+.

GitHub: GitHub - genticai-pro/agentguard: Production reliability for n8n AI agents. Drop-in. Zero dependencies. Battle-tested. · GitHub


Question for the community: What failure modes have you hit in production that these don’t cover? Specifically curious about multi-agent patterns, webhook-triggered agents, and anything involving file system tools. Want to add recovery strategies for patterns we haven’t seen yet.

إعجابَين (2)

This is the right kind of boring reliability work. I like the pattern of treating retries, context budget, and approval as separate reusable pieces instead of one giant prompt. Not sexy, but it works.

Separating these into reusable sub-workflows is the right shape. Reliability logic gets messy fast when retry decisions, context limits, and permission checks all live inside one giant agent workflow.

For production use, I would make each reliability sub-workflow emit a small receipt, not just pass/fail:

  1. RetryClassifier: retry reason, final decision, attempt count, and next action.
  2. ContextBudget: what was trimmed or rejected, and whether the run degraded safely.
  3. PermissionGate: requested action, approved/denied state, approver or policy rule, and timestamp.
  4. Shared fields: client/workflow/run id, external side effect attempted, and business impact if known.

That way a silent lead drop becomes an issue you can investigate instead of a mystery. The sub-workflow protects the run; the receipt protects the operating trail afterward.

The ContextBudget one solves a specific pain point I’ve run into with RAG-heavy agents that hit tool output size limits mid-run and fail silently. Checking token headroom before each tool call, rather than after the fact, is the right direction. One thing I’d add for multi-step research agents: pass the estimated remaining budget as a value downstream so the agent can adjust retrieval depth (fewer chunks, smaller top_k) instead of hard-stopping mid-run.

إعجاب واحد (1)

The 27-hour incident you described is the clearest example of the difference between process health and data path health. The /healthz endpoint confirmed that n8n was running and responding. It said nothing about whether n8n could actually complete a workflow.

The three sub-workflows handle in-flight reliability: what happens when a workflow is executing and something goes wrong. The gap that remains is pre-flight: can the stack actually run workflows right now?

A fourth sub-workflow fits the same pattern. Call it something like InfraCanary:

Schedule trigger every 5-10 minutes. A minimal known-good test: write a timestamp to a scratch location (a dedicated SQLite row, a test sheet row, a short-TTL cache entry), then read it back in the same execution. IF node: does the retrieved value match what was written, within the expected window? If not, fire the same alert path the rest of your monitoring uses.

This catches exactly the failure from the incident. The /healthz check can return 200 while this probe fails, because the probe exercises the actual data path rather than the HTTP process. Four webhook callers with silent catch blocks would still have generated nothing, but the canary would have fired within 10 minutes of the SQLite layer going down.

Rory’s receipt pattern applies here too. On each successful run, emit a small record: last_ok_timestamp, probe_duration_ms. If the canary itself fails to emit, the absence of that record is the alert.

The existing three sub-workflows become more trustworthy when you know the infrastructure they run on is validated by something other than its own health endpoint.