SafeAgent — community node to prevent duplicate side effects in n8n workflows

:shield: SafeAgent — community node to prevent duplicate side effects in n8n workflows

Package: n8n-nodes-safeagent (v0.1.1)
Install: Settings → Community Nodes → n8n-nodes-safeagent


The problem

n8n workflows can trigger the same irreversible action more than once.

Webhook fires twice. Agent retries. Workflow restarts mid-run. The trigger node doesn’t know the action already happened — so it happens again.

  • Email sent twice
  • Payment charged twice
  • Trade executed twice
  • API call duplicated

n8n handles retries at the transport layer. Nothing in the workflow itself tracks whether the side effect already ran. That gap is where duplicates happen.


What this node does

SafeAgent adds a claim-before-execute step before any irreversible action.

Webhook fires → SafeAgent claims request_id → action runs → marked SETTLED
Webhook fires again → SafeAgent sees SETTLED → action is skipped

The node has two outputs: Proceed and Skip. Wire your action to Proceed. Done.


Quick example

Duplicate-safe webhook → email:

[Webhook] → [SafeAgent] → (Proceed) → [Send Email]
                        → (Skip)    → [Stop / Log]

If the same webhook payload arrives twice (same request_id), the email sends once. The second execution exits through Skip automatically.

Works for any irreversible action — emails, payments, Slack messages, database writes, API calls.


Setup

Requires Python 3.10+ and the pip package on the same host as n8n:

pip install safeagent-exec-guard

Docker users: there’s a Dockerfile snippet in the README to extend the base n8n image.

For multi-instance / distributed n8n, Postgres is supported instead of the default SQLite.


Node fields

Field What to put
request_id Unique ID per execution — use {{ $json.headers["x-request-id"] }} or generate one
action Label for the action being guarded (send_email, charge_card, etc.)
db_path SQLite path or Postgres connection string

Background

I built this while working on a live trading bot. The bot was retrying on network timeouts — and executing the same trade twice. I looked for something to guard against this in n8n and couldn’t find it, so I built it.

The same problem shows up everywhere agents retry: payments, notifications, ledger entries. The fix is always the same — track the claim before you execute.

SafeAgent is also available as a Python package (safeagent-exec-guard) and in the MCP registry (io.github.azender1/safeagent) for non-n8n use cases.


Feedback welcome

This is v0.1.1 — early. If you install it and something doesn’t work, or you hit friction in the setup, I want to know. Open an issue on GitHub or reply here.

Specifically looking for feedback on:

  • Does the Docker setup work cleanly for you?
  • Is the Python dependency a dealbreaker for your setup?
  • What actions are you guarding?

— Anthony Zender, Dayton OH
azender1@yahoo.com | GitHub

1 Like