## TL;DR
A double escalation means the escalation action ran twice without knowing about the first run: two triggers, a retry after a timeout, or two agents acting in parallel. Make escalation idempotent: record that the ticket is escalated (a tag, a field, a dedup key), check the record before escalating, and use atomic check-and-set where races are possible. One ticket, one escalation.

## The query

```text
escalation fired twice on the same ticket: dedup guard
```

## Use this when

- Escalations fire twice on one ticket
- Customers get double-handled
- Escalation notifications duplicate
- You are building escalation automation

## Not for

- Designing escalation policies
- Staffing escalation teams
- Writing escalation notification copy
- Escalation SLA design

## Steps

### 1. Record the escalation as structured state

When escalating, write a marker the system can check: an "escalated" tag, a custom field with timestamp, or a dedup key in your store. The marker is the memory that prevents the second firing.

Expected output: a checkable escalation marker on every escalation.

### 2. Check the marker before escalating

Every escalation path reads the marker first. Already escalated means skip (or update the existing escalation, never create a second). The check is the dedup guard; everything else is backup.

Expected output: marker check gating all escalation paths.

### 3. Make the check-and-set atomic where races exist

Two agents escalating simultaneously can both read "not escalated" and both write. Where parallelism is real, use an atomic operation or a unique constraint so only one wins. Races need atomicity, not just checks.

Expected output: atomic escalation claiming under concurrency.

### 4. Handle retries as idempotent replays

A timeout after the escalation sent but before the response arrived causes a retry that looks like a second escalation. Design the send to be retry-safe: same dedup key, same marker, no duplicate side effects.

Expected output: retry-safe escalation sends.

### 5. Alert on double-escalation attempts

Log every skipped-as-duplicate escalation. A rising skip rate means two paths are racing or a trigger is misfiring; the log points at the redundant path. Skips are diagnostics, not just prevented bugs.

Expected output: duplicate-attempt monitoring.

## Template: the checklist

```text
Escalation dedup:
[ ] Escalation marker written as structured state
[ ] Marker checked before every escalation
[ ] Atomic check-and-set under concurrency
[ ] Retries safe via dedup keys
[ ] Duplicate attempts logged and monitored
```

## Variant phrasings

### ticket escalated twice

Steps 1 and 2. Marker, then check.

### duplicate escalation notification

Steps 2 and 4. Check plus retry safety.

### escalation trigger firing twice

Steps 1 and 5. Marker plus attempt monitoring.

## Why it happens

Escalation gets triggered from multiple places: a trigger on SLA breach, an agent clicking escalate, an automation on sentiment. Each path was built assuming it is the only one, so none checks for the others' work. Redundant paths plus no shared memory equals double escalation. The marker is the shared memory the paths were missing.

## Edge cases

- Legitimate re-escalation: a ticket escalated, resolved, then genuinely needing escalation again. Design the marker to reset on resolution.
- Escalation to different teams: escalating to billing then to engineering may both be valid. Dedup per target, not just per ticket.
- Marker write failing: if the marker write fails but the escalation sent, the next check misses it. Write the marker first or transactionally.
- Escalation via email: email-based escalations lack atomic markers. Use the ticket-side marker as the authority.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_A8tBWIZPqv7r25tpzsKOxA
