Skip to main content

Plan Not Found

plan_not_found422

Validation · Affects all endpoints

The requested plan doesn't exist. Use a valid plan ID from the pricing page.

What this means

A request referenced a billing plan by ID, and we don't have a plan matching that identifier. Either the plan ID was mistyped, refers to a plan that's been retired, or refers to a plan from a different environment (staging vs production). The action (subscribe, upgrade, downgrade) was not performed.

When you'll see this

  • A subscribe request used a plan ID that no longer exists (a retired tier).
  • A typo introduced an incorrect plan ID.
  • A staging plan ID was used in production code or vice versa.
  • An internal mapping between Asterwise plans and a third-party catalog drifted.
Learn more about how this works

Plan IDs are stable strings tied to specific tier/pricing combinations: Sandbox (free), Builder, Launch, Scale. These IDs are documented on the pricing page and don't change as long as the plan is offered. When a plan is retired (rare), its ID stops being valid and requests using it return this error.

The most common gotcha: this error is sometimes confused with subscription_not_found. They're different layers. plan_not_found means the plan catalog doesn't have the requested entry. subscription_not_found means the account has no active subscription record. One is about what plans exist; the other is about what plans the account is on.

Example response

{
"success": false,
"error": "plan_not_found",
"message": "The specified plan does not exist.",
"details": [],
"retry_after": null,
"doc_url": "https://docs.asterwise.com/reference/errors/plan_not_found",
"request_id": "req_01HXYZABCDEFGH",
"timestamp": "2026-05-25T12:34:56Z"
}
NEW TO APIS?
Quick fix
  1. Verify the plan ID in your code matches one of the valid plan IDs (Sandbox, Builder, Launch, Scale — exact slugs from the pricing page).
  2. If you're using a staged or test plan ID, swap to the production plan ID before deploying.
  3. If you're sure the plan should exist and it doesn't, email [email protected] — retired plans without notice are unusual but worth flagging.
PRODUCTION ENGINEER
Recovery pattern

Hard validation error; surface clearly during integration. Should never reach production code with valid plan IDs.

Python:

Production handler

import httpx

VALID_PLAN_IDS = {"sandbox", "builder", "launch", "scale"}

def subscribe(plan_id, base_url, headers):
if plan_id not in VALID_PLAN_IDS:
raise ValueError(f"Invalid plan_id: {plan_id}")
response = httpx.post(
f"{base_url}/v1/billing/subscribe",
headers=headers,
json={"plan_id": plan_id},
timeout=15,
)
if response.status_code == 422:
body = response.json()
if body.get("error") == "plan_not_found":
raise RuntimeError(
f"Plan {plan_id} not recognized by server. "
f"Check against asterwise.com/pricing."
)
response.raise_for_status()
return response.json()

Avoid this error by

  • Keep plan IDs in a constants file or enum on your side. Reference plans by named constant, not raw string.
  • Don't hardcode plan IDs in user-facing forms. Fetch the current valid set if needed.
  • In integration tests, verify each plan ID your code uses against a live request. Catches typos at CI time.
  • When migrating environments, audit plan IDs as part of the migration. They're stable but not portable across providers.