idempotency_key_in_use
The first request with this `Idempotency-Key` is still running. Wait, then retry with the same key.
HTTP 409The resource is not in a state that allows this operation.
When it fires
A request with this Idempotency-Key is still running, and its outcome is not known yet. It happens when a client times out and retries while the first attempt is still being processed, or when two workers pick up the same job at once. The second request was not run.
Response shape
Every Repull error follows the same envelope. The code is stable and safe to switch on.
{
"error": {
"code": "idempotency_key_in_use",
"message": "A request with this `Idempotency-Key` is still in flight. Its outcome is not known yet.",
"fix": "Wait for the original request to return, then retry with the SAME key to receive its stored response. Do not switch keys — that would send a second request.",
"field": "Idempotency-Key",
"value_received": "msg-164743-checkin",
"docs_url": "https://repull.dev/docs/errors/idempotency_key_in_use",
"request_id": "req_01J5X7Y8Z9ABCDEF12345678"
}
}How to fix
- Wait a few seconds, then retry with the same key. Once the first request finishes you get its stored response, marked `Idempotency-Status: cached`.
- Do not switch to a new key to get past this. That would run the action a second time, which is exactly what the key prevents.
Common gotchas
- Set your client timeout longer than the slowest action you call. Sending a message with attachments or sending a special offer can take several seconds.
- If the first request ends in a server error or a
429, nothing is stored, and your retry with the same key runs for real.
Examples
curl
# Same key, a few seconds later
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."}'TypeScript
async function postIdempotent(url: string, body: unknown, key: string) {
for (let i = 0; i < 5; i++) {
const res = await fetch(url, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.REPULL_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': key, // never changes between attempts
},
body: JSON.stringify(body),
})
if (res.status !== 409) return res
const { error } = await res.clone().json()
if (error.code !== 'idempotency_key_in_use') return res
await new Promise((r) => setTimeout(r, 2000 * (i + 1)))
}
throw new Error('first request still running')
}If you're an AI agent
The first request with this Idempotency-Key is still running. Wait, then retry with the SAME key to get its stored response. Never switch keys to get past it.
Related
- Error reference — the full table of error codes
- Using Repull from AI agents — patterns for handling errors in agent loops
- Idempotency Keys
- idempotency_key_reused
Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.
AI