Commune

409conflict

Idempotency key conflict

The `Idempotency-Key` on this write was already used for a different request, or a request with the same key has not finished.

Every write carries an Idempotency-Key. Commune records the key with a fingerprint of the request before making the change, and for the next 24 hours a request with the same key from the same credential is treated as a retry of the first: if it is identical, you get the first answer back (with Idempotent-Replay: true) and nothing happens twice.

This error is that mechanism refusing something that is not a clean retry. Nothing was changed by a request that answers `409`. param is Idempotency-Key, and the message says which of the two cases you hit.

A write that failed with a 4xx releases its key, so after fixing a 400 or 422 you may send the corrected request with the same key. A 5xx keeps the key claimed, because its outcome is unknown.

Why it happens, and how to fix it

  1. The key was already used for a different request

    The same key arrived with a request that differs from the first one that used it: a different body (even a reordered or reformatted JSON body counts, because the raw bytes are compared), different query parameters, a different path, a different Commune-Version, or a different operation altogether. Usually this is code that reuses a constant key, or derives the key from something that does not change between distinct writes.

    Fix: Generate a fresh key (a UUID) for each distinct change, and reuse a key only to retry the exact same request, byte for byte, including the Commune-Version header. Store the key with the pending change so a retry sends it unchanged.
  2. A request with the same key is still in flight

    An earlier request with this key is still running, typically because a client timed out and retried immediately, or two workers picked up the same job. The same happens for up to 60 seconds after an attempt that ended in a 5xx or never reported an outcome.

    Fix: Wait the number of seconds in Retry-After, then retry with the same key and the same request. You will get the first attempt's answer, marked Idempotent-Replay: true, or the claim will have expired and your retry runs.

Retrying

Only for the in-flight case: wait Retry-After and resend the identical request with the same key; for a reused key, send the new request with a new key.

Headers

  • Retry-After

    Seconds to wait before retrying, sent only when the other request is still in flight (5 seconds).

  • Idempotent-Replay

    Not on this error. It is true on a later successful response that was replayed from the first request with the same key rather than performed again.

Example response

HTTP 409
{
  "error": {
    "code": "conflict",
    "message": "The Idempotency-Key \"4d6f8e2a-9b1c-4c3d-8e7f-0a1b2c3d4e5f\" was already used for a different request, on this same operation with different parameters. A key names one change: reuse it only to retry that exact request, and send a new value for a different one. Nothing was changed by this request.",
    "param": "Idempotency-Key",
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.dev/errors/conflict"
  }
}

Often confused with bad_request, rate_limited.