koala73/worldmonitor · error · Error
[sendProLaunchBroadcast] Resend ${res.status}: ${errBody}
Error message
[sendProLaunchBroadcast] Resend ${res.status}: ${errBody} What it means
Thrown when Resend's POST /broadcasts/{broadcastId}/send endpoint returns a non-2xx status during sendProLaunchBroadcast. The error includes the HTTP status and raw response body. This is the send (fire) step — the broadcast was already created successfully.
Source
Thrown at convex/broadcast/sendBroadcast.ts:174
const body: Record<string, unknown> = {};
if (scheduledAt) body.scheduled_at = scheduledAt;
const res = await fetch(
`${RESEND_API_BASE}/broadcasts/${encodeURIComponent(broadcastId)}/send`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
"User-Agent": USER_AGENT,
},
body: JSON.stringify(body),
},
);
if (!res.ok) {
const errBody = await res.text().catch(() => "<no body>");
throw new Error(
`[sendProLaunchBroadcast] Resend ${res.status}: ${errBody}`,
);
}
return {
broadcastId,
status: scheduledAt ? "scheduled" : "queued",
scheduledAt: scheduledAt ?? null,
};
},
});
View on GitHub (pinned to ffec79ac33)
Solutions
- Check the status code: 404/409 means the broadcastId is gone or already sent — inspect the Resend dashboard to determine the true state before retrying.
- If 409 (already sent), do NOT retry; instead record the send state in the waveRuns row to prevent re-sending.
- For 429 or 5xx, retry with exponential backoff — the send endpoint is designed to be retryable for transient failures.
- If the broadcast was deleted, create a new one via createProLaunchBroadcast and send the new id.
Defensive patterns
Strategy: retry
Try / catch
try {
await ctx.runAction(internal.broadcast.sendBroadcast.sendProLaunchBroadcast, { broadcastId });
} catch (err) {
const msg = String(err);
if (msg.includes("Resend 409")) {
// already sent — record state, do not retry
throw new Error(`Broadcast ${broadcastId} already sent or in conflict`);
}
if (msg.includes("Resend 404")) {
// broadcastId gone — recreate via createProLaunchBroadcast
throw err;
}
if (msg.includes("Resend 429") || msg.includes("Resend 5")) {
// transient — retry with backoff
throw err; // let scheduler retry
}
throw err;
} Prevention
- Record the broadcast send state in the waveRuns row immediately after success to prevent duplicate sends.
- Before retrying a failed send, inspect the Resend dashboard to confirm the broadcast was not already sent.
- Treat 409 (already sent) as a terminal state, not a retryable error.
When it happens
Trigger: The broadcastId does not exist or was already sent (Resend 404/409). The broadcast was deleted between create and send. Rate limiting (429). Resend 5xx outage. The RESEND_API_KEY lacks send permissions for this broadcast.
Common situations: The operator created a broadcast, then deleted it in the Resend dashboard before sending. The same broadcastId was sent twice (double-click, duplicate schedule). A Resend outage occurs between broadcast creation and the send call. The broadcast was already sent by a previous run that did not record its result.
Related errors
- [createProLaunchBroadcast] Resend ${res.status}: ${body}
- [createProLaunchBroadcast] Resend response missing id: ${JSO
- [backfillCanary250] Resend list-contacts ${res.status}: ${bo
- [assignAndExportWave] waveLabel "${waveLabel}" already has s
- [assignAndExportWave] pool empty — all registrations are sup
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/1dd6e12e6971255f.
Report an issue: GitHub.