Commune

422unprocessable

Refused by current state

The request is well formed, and the current state of what it addresses refuses it. The message says what is in the way.

Every value in the request is legal, and the thing it acts on is not in a state that allows it: an article that has already been sent, a newsletter with no verified sending address, a slug another article already uses. Changing the request's syntax will not help. Changing the state will, or choosing a different target.

Most of these come from the article lifecycle (POST /articles/{article}/send, /schedule, /unschedule, /test-send, and PATCH /articles/{article}) and from tags. param is set when one field is responsible (slug, name, tag, attempt). The message always says what state is in the way, and nothing was changed.

A newsletter that is published through another provider has its own code, not_commune_newsletter.

Why it happens, and how to fix it

  1. The newsletter cannot send yet

    Sending, scheduling and test sends need a sending address. The newsletter has none, or its address is not verified yet (the message gives the verification state).

    Fix: Add or verify the sending address on the newsletter's Domains page in the Commune dashboard. GET /newsletters/{newsletter}/senders and GET /senders/{sender} report each address's state and the DNS records that complete verification.
  2. The article cannot be sent as it is

    The send and schedule gates refused the article's body. It is empty. Or it is missing the unsubscribe link, the mailing address ({{ address }}), or both, which commercial email must carry; Commune seeds them into every draft and this gate cannot be bypassed. Or an image in it could not be loaded, which would break it for every recipient (an image host that is only slow is never reported).

    Fix: Put content in the body (content_markdown on PATCH /articles/{article}). Restore the unsubscribe link and mailing address that were edited out of the footer. For images, re-upload or remove the ones the message lists, or send again with {"acknowledge_broken_images": true} in the body if you accept them broken.
  3. The article is in the wrong state

    Only a draft, a scheduled article or one whose last send failed can be sent or scheduled; one that is sending, sent or archived cannot. POST /articles/{article}/unschedule needs an article that is scheduled. PATCH /articles/{article} refuses an article that is sending (wait for it to finish), sent (an email cannot be recalled), archived (unarchive it in Commune first), or imported from the newsletter's provider (it can never be edited here).

    Fix: Read the article with GET /articles/{article} and check status and is_imported, then act on what it says. To send the same content again, create a new article.
  4. The state changed during the request, or the time has passed

    The article moved between the check and the change, usually because another request sent or scheduled it at the same moment. On POST /articles/{article}/schedule, a scheduled_for in the past is refused the same way rather than sent immediately.

    Fix: Read the article again and decide from its current status. For scheduling, send a scheduled_for in the future, in UTC or with an explicit offset.
  5. A slug or tag name is already taken

    Article slugs are unique within a newsletter, and tag names are unique among a newsletter's live tags. param is slug or name.

    Fix: Choose another value. For an article, you can leave slug out and Commune derives a free one from the title.
  6. The tag is retired

    A tag that was deleted after an article was sent to it is kept as retired, because it still decides who may read that article. A retired tag cannot be renamed or added to anyone new (param is name or tag). Removing it from a subscriber still works.

    Fix: Create a new tag with POST /newsletters/{newsletter}/tags and use that instead. GET /tags/{tag} shows whether a tag is retired.
  7. Other refusals with a clear target

    POST /threads/{thread}/publish was given the id of a reply rather than a thread. POST /delivery-attempts/{attempt}/replay was asked to redeliver to a destination that is switched off (param is attempt). A test send was refused by the sending service for a reason the message quotes.

    Fix: Publish the thread the reply belongs to (its id is the thread on the message). Enable the destination in the delivery portal, which POST /newsletters/{newsletter}/portal-session opens, then replay. For a test send, act on the reason in the message.

Retrying

No: the same request is refused until the state it names changes, so fix that state (or pick another target) and then send it again, with the same Idempotency-Key if you like, since nothing was changed.

Example response

HTTP 422
{
  "error": {
    "code": "unprocessable",
    "message": "This newsletter's sending address is not verified, so no email can go out from it. Its verification is `pending`. The DNS records that finish verification are on the sender, which the `senders` operations return.",
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.dev/errors/unprocessable"
  }
}

Often confused with not_commune_newsletter, bad_request, conflict.