message_send_failed
A message send failed for a reason Repull could not classify, usually the channel being unavailable. Retry with the same `Idempotency-Key`.
When it fires
Sending a message failed for a reason Repull could not match to a more specific code: not a refusal by the channel (that is message_not_sent) and not a problem with the request (that is invalid_params). It usually means the channel was unavailable or timed out. It is returned as 502, or as the server error status that was reported, and message carries what was reported.
Response shape
Every Repull error follows the same envelope. The code is stable and safe to switch on.
{
"error": {
"code": "message_send_failed",
"message": "Message send failed: <what was reported>",
"docs_url": "https://repull.dev/docs/errors/message_send_failed",
"request_id": "req_01J5X7Y8Z9ABCDEF12345678"
}
}How to fix
- Retry the same request with the same `Idempotency-Key`, backing off between attempts. Server errors are not stored against a key, so the retry runs for real and still cannot send twice.
- Before retrying after a long gap, you can check whether the message went out after all with `GET /v1/conversations/{id}/messages`.
- If it keeps failing, email hello@repull.dev with the `request_id`.
Common gotchas
- Always send an
Idempotency-Keywith messages. Without one, a retry after a timeout can send the guest the same message twice. - A channel refusal (links, email addresses or phone numbers in the text) is
message_not_sent, not this code. Retrying that one unchanged will be refused again.
Examples
curl
curl -X POST https://api.repull.dev/v1/conversations/164743/messages \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Idempotency-Key: msg-164743-checkin" \
-H "Content-Type: application/json" \
-d '{"message": "Your check-in details are ready."}'
# → 502 message_send_failed: run the same command again after a short waitTypeScript
async function sendWithRetry(doSend: () => Promise<Response>, attempts = 4) {
for (let i = 0; i < attempts; i++) {
const res = await doSend() // same Idempotency-Key on every attempt
if (res.status < 500) return res
const { error } = await res.clone().json()
if (error.retryable === false) return res // e.g. service_misconfigured
await new Promise((r) => setTimeout(r, 2 ** i * 1000 + Math.random() * 250))
}
throw new Error('message send kept failing')
}If you're an AI agent
A message send failed for an unclassified reason, usually the channel being unavailable. Retry with the same Idempotency-Key and backoff; check GET /v1/conversations/{id}/messages first after a long gap; report the request_id if it persists.
Related
- Error reference — the full table of error codes
- Using Repull from AI agents — patterns for handling errors in agent loops
- Send a Message
- message_not_sent
- Idempotency Keys
Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.