Skip to main content

Already On Plan

already_on_plan400

Billing · Affects all endpoints

The account is already subscribed to this plan. No change was made.

What this means

A request tried to subscribe an account to a plan it's already on. We refuse the request rather than processing a duplicate charge or modifying the existing subscription's billing cycle. The account's current plan, limits, and renewal date are unchanged. No money moved.

When you'll see this

  • A user clicked "Subscribe to Builder" while already on Builder (often a UI race condition where stale subscription state was displayed).
  • A retry-on-error logic re-submitted a checkout request that had actually succeeded the first time.
  • An automated migration script tried to "ensure" a plan that was already active.
  • A user navigated back to checkout after completing payment in another tab.
Learn more about how this works

Asterwise enforces one active plan per account. Upgrading to a higher tier or downgrading to a lower one is a different flow than fresh subscription — those go through /v1/billing/upgrade, not /v1/billing/subscribe. Hitting subscribe on the current plan does nothing useful, so we surface a clear signal rather than silently no-op'ing.

In practice: this error usually points to stale UI state. The user thinks they're on plan A and trying to upgrade to plan B, but they were already moved to plan B in a previous session. Refreshing the dashboard usually clears the confusion.

Example response

{
"success": false,
"error": "already_on_plan",
"message": "You are already on this plan.",
"details": [],
"retry_after": null,
"doc_url": "https://docs.asterwise.com/reference/errors/already_on_plan",
"request_id": "req_01HXYZABCDEFGH",
"timestamp": "2026-05-25T12:34:56Z"
}
NEW TO APIS?
Quick fix
  1. Refresh asterwise.com/dashboard — your current plan will be displayed accurately.
  2. If you wanted to upgrade or downgrade, use the dedicated upgrade/downgrade flow, not "Subscribe".
  3. If the dashboard shows a different plan than you're being told you're already on, email [email protected] with the request_id — that's a state-sync issue we should look at.
PRODUCTION ENGINEER
Recovery pattern

This isn't a failure — it's confirmation that no change was needed. Treat it as success in your subscription-management code.

Python:

Production handler

import httpx

def ensure_subscription(plan_id, base_url, headers):
response = httpx.post(
f"{base_url}/v1/billing/subscribe",
headers=headers,
json={"plan_id": plan_id},
timeout=15,
)
if response.status_code == 400:
body = response.json()
if body.get("error") == "already_on_plan":
return {"ok": True, "status": "no_change_needed"}
response.raise_for_status()
return {"ok": True, "status": "subscribed", "data": response.json()}

Avoid this error by

  • Check the current subscription state before showing a "Subscribe" button. If the user is already on the target plan, show "Current plan" instead.
  • Disable the Subscribe button immediately after the first click to prevent double-submission races.
  • Use the dedicated upgrade endpoint when changing tiers, not the subscribe endpoint.
  • Don't use idempotency keys to "force" re-subscription — they don't work that way for this flow.