---
id: "exactly-once-with-external-side-effects"
type: "rule"
severity: "warning"
url: "https://localhost:3000/catalogue/rules/exactly-once-with-external-side-effects"
---

# Exactly-once delivery in front of an external side effect

An edge claims exactly-once delivery to a node that then calls a third party synchronously, which exactly-once cannot cover.

| | |
|---|---|
| Severity | warning |
| Selects | every edge declaring exactly-once delivery |
| Components in scope | 2,366 |

## Why

Exactly-once delivery stops at the consumer. When that consumer then calls a third party synchronously, the side effect sits outside the transaction and can still happen twice, so the exactly-once claim hides the need for an idempotent external call.

## What it checks

It looks at every edge declaring exactly-once delivery, and fires when:

- the edge's target node:
  - the node has at least one synchronous outgoing edge to a third-party-api

Message template:

```
Edge '{{edge.from}}' -> '{{edge.to}}' claims exactly-once delivery, but '{{edge.to}}' calls a third party synchronously. Exactly-once cannot cover that side effect; make the external call idempotent instead.
```

## Applies to

This rule is about an edge, so it belongs to a pair of nodes rather than one component.

2,366 catalogue components fall under it.

## Tripped by

Reference designs whose broken twin names this rule in its header:

- [distributed-email](https://localhost:3000/d/zeema/distributed-email)
- [distributed-message-queue](https://localhost:3000/d/zeema/distributed-message-queue)
- [duolingo-backend](https://localhost:3000/d/zeema/duolingo-backend)
- [grab-geo](https://localhost:3000/d/zeema/grab-geo)
- [nubank-core](https://localhost:3000/d/zeema/nubank-core)
- [payment-system](https://localhost:3000/d/zeema/payment-system)

## Source (`rule` YAML, verbatim)

```yaml
# yaml-language-server: $schema=../schema/rule.schema.json
# Exactly-once delivery stops at the consumer. If the consumer then calls a third party
# synchronously, that side effect is outside the transaction and can still happen twice.
# Claiming exactly-once here hides the need for idempotent external calls.
# Tripped by: designs/payment-system.broken.yaml
schemaVersion: "1"
type: "rule"
id: "exactly-once-with-external-side-effects"
severity: "warning"
select:
  edge:
    delivery: "exactly-once"
when:
  to:
    hasEdge:
      direction: "out"
      mode: "sync"
      peerKind: "third-party-api"
message: "Edge '{{edge.from}}' -> '{{edge.to}}' claims exactly-once delivery, but '{{edge.to}}' calls a third party synchronously. Exactly-once cannot cover that side effect; make the external call idempotent instead."
```

Human page: https://localhost:3000/catalogue/rules/exactly-once-with-external-side-effects
