attachment_unreachable
An attachment URL could not be downloaded: an error status, an empty file, or no answer within 20 seconds. Nothing was sent.
When it fires
Repull tried to download one of the attachments and could not get the file. index and field name which one, and message says what happened:
- the URL answered with an error status, such as
403from an expired signed URL or404; - the URL answered with an empty body;
- the server did not answer within 20 seconds, or the connection failed.
Every file is checked before anything is delivered, so nothing was sent to the guest.
Response shape
Every Repull error follows the same envelope. The code is stable and safe to switch on.
{
"error": {
"code": "attachment_unreachable",
"message": "Attachment 0: the URL returned HTTP 403. Nothing was sent.",
"fix": "Make sure the URL is publicly readable (a signed URL must not have expired), then send again.",
"docs_url": "https://repull.dev/docs/errors/attachment_unreachable",
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
"field": "attachments[0]",
"channel": "airbnb",
"index": 0
}
}How to fix
- Open the URL named by `index` without any cookies or login, for example with `curl -I`. It must return 200 and the file itself.
- If it is a signed URL, generate a fresh one just before the send; an expired signature answers 403.
- Make sure the URL points at the file, not at a web page that links to it.
- Send the request again with a new `Idempotency-Key`. A 422 is stored against the key it was sent with, so reusing that key replays the same refusal.
Examples
curl
# Check the file is publicly downloadable first
curl -I "https://cdn.example.com/parking-map.jpg"
# → HTTP/2 200, content-type: image/jpeg
curl -X POST https://api.repull.dev/v1/conversations/164743/messages \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "Here is the parking map.", "attachments": [{"url": "https://cdn.example.com/parking-map.jpg"}]}'TypeScript
const res = await fetch('https://api.repull.dev/v1/conversations/164743/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REPULL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ message: 'Here is the parking map.', attachments }),
})
if (res.status === 422) {
const { error } = await res.json()
if (error.code === 'attachment_unreachable') {
// error.index names the file; regenerate its signed URL and send again
console.warn(`Could not download attachment ${error.index}: ${error.message}`)
}
}If you're an AI agent
Repull could not download one attachment (error status, empty file or timeout). Nothing was sent. Check the URL named by `index` is publicly downloadable (regenerate an expired signed URL) and send again.
Related
- Error reference — the full table of error codes
- Using Repull from AI agents — patterns for handling errors in agent loops
- Sending attachments
- attachment_url_not_allowed
Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.