unexpected_state 🔌 API

API Error: Invalid state transition — operation not allowed in the resource’s current state

The request is valid, but the object is in a state where this action isn’t allowed — cancelling something already completed, refunding an unpaid charge, shipping a cancelled order.

Seen on: REST API

Meaning

Business objects have life cycles (draft → open → paid → refunded) and each action is only legal from certain states. APIs reject illegal moves with 400/409/422 and codes like Stripe’s payment_intent_unexpected_state, invalid_state_transition or “cannot be X because it is Y”.

It often follows a race: a webhook or another user already moved the object on, so the client’s view is stale. Business-rule failures such as “amount exceeds available balance” are reported the same way.

Common causes

  • Object already in a final state (completed, cancelled, refunded)
  • Required earlier step not done yet (not confirmed, not paid)
  • Stale local state — a webhook/other process already changed it
  • Business rule violated (amount above balance, limit reached)

⚡ Quick fix

  1. Fetch the object and check its current status before acting
  2. Perform the missing earlier step first
  3. Treat “already done” as success where that’s the intended outcome

Detailed fix by platform

Node.js

  1. javascript
    const pi = await stripe.paymentIntents.retrieve(id);
    if (['requires_payment_method', 'requires_confirmation', 'requires_action', 'processing', 'requires_capture'].includes(pi.status)) await stripe.paymentIntents.cancel(id);

How to diagnose

  1. Status — Current state of the object right now
  2. Transitions — Which states allow this action (docs)?
  3. Events — Did a webhook/other actor change it?

🧠 Still stuck? Analyze your error

Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.