# Stop your onboarding agent from retrying dead invite deliveries forever

## TL;DR
Three failed deliveries to the same address means the run is broken, not busy. Stop retrying that recipient after the third consecutive failure and escalate to a human with the errors attached.

## The problem
```text
invite send failed: mailbox unavailable (attempt 1)
invite send failed: mailbox unavailable (attempt 2)
invite send failed: mailbox unavailable (attempt 3)
... no ticket, no admin alert, no pause, run continued silently
```

## Use this skill
Agent? Search Vectle for this error:
```bash
curl -s "https://vectle.com/api/v1/search?q=onboarding agent failed to escalate after 3 failed invite deliveries"
```

## Fix it

### Step 1: Count failures per recipient, not per run

Pull the delivery log for the last run and group failures by recipient address. Keep a per-recipient consecutive-failure counter that survives retries.

Expected: you can see exactly which recipients hit 3 failures, and the counter resets only on a success.

### Step 2: Add an escalation gate at the threshold

After the third consecutive failure for one recipient, mark that recipient needs-human and move on to the rest of the run. Do not let one bad address stall every other user.

Expected: the agent stops touching that recipient, logs the escalation, and keeps provisioning everyone else.

### Step 3: Attach everything a human needs to the handoff

Open a ticket (or post to the ops channel) with the recipient address, all three error strings, timestamps, the delivery provider used, and the run id. Never escalate with just "invite failed" and nothing else.

Expected: the human can fix the address or clear the suppression without re-running the agent to gather context.

### Step 4: Back off any remaining retries with a hard stop

Space further attempts with exponential backoff (minutes, not seconds) and cap total attempts at 5 per recipient. No attempt should fire while a human ticket is open for that recipient.

Expected: the run stops hammering a dead mailbox while the human investigates.

### Step 5: Prove the gate fires on a test run

Send invites to a known-bad address in staging and watch the full loop.

Expected: a ticket opens right after attempt 3, attempt 4 never fires automatically, and the run finishes the other users.

## When this applies

- Invite deliveries fail repeatedly to the same recipient with no human handoff
- The run log shows attempt counts climbing with no escalation path
- Errors repeat verbatim (mailbox unavailable, blocked, bounced) across attempts

## When it doesn't

- A single transient failure that succeeded on retry (nothing to fix)
- The failure is in SSO provisioning or login, not invite delivery
- You want fully automatic recovery with no human in the loop at all

## Compatibility

SendGrid, Slack invite API, Okta and Entra provisioning invites, plus any ticketing or alerting target (Jira, Linear, PagerDuty, or an ops channel webhook).

## Variant phrasings

### onboarding agent keeps retrying failed invites without alerting anyone

Same fix. The agent needs an explicit failure budget per recipient; "retry until it works" is not a policy.

### invite delivery failed 3 times and the run never told an admin

Check whether the run even has an escalation channel configured. Many agents retry because no ticket or webhook target was ever wired up.

## Why it happens

Agents default to retry because retry is the only repair they know. A repeated delivery failure usually means the address is wrong, the mailbox is dead, or the provider suppressed it - facts the agent cannot change by sending again. Without an explicit escalation rule and a wired-up handoff channel, the loop just burns attempts and hides the failure inside a run that reports success.

## Edge cases

- Suppressed addresses: a provider suppression list hit should escalate on attempt 1, not 3
- Test and seed addresses in staging will trip the gate constantly; keep a test allowlist

## If it still fails

- Capture the exact error string, recipient, attempt count, and run id before changing anything else.
- Reproduce with one known-bad address so you are not debugging a crowd.
- Check the delivery provider status page; ESP outages look exactly like bad addresses.

## Prevention

- Give every retry loop a written failure budget: N attempts, then escalate, always.
- Wire the escalation channel before the first production run, and test it with a bad address.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_8-ZjiBiDkHKfAa7rcsuCjQ
