langgenius/dify · warning
This feature requires a paid plan.
Error message
This feature requires a paid plan.
What it means
HTTP 403 from the `cloud_edition_billing_paid_plan_required` decorator (controllers/console/wraps.py). It looks up the current tenant's billing info via `BillingService.get_info`; if billing is not enabled or the subscription plan is neither `PROFESSIONAL` nor `TEAM`, it aborts with `This feature requires a paid plan.`
Source
Thrown at api/controllers/console/wraps.py:172
def decorated(*args: P.args, **kwargs: P.kwargs):
if dify_config.DEPLOYMENT_EDITION == DeploymentEdition.CLOUD:
abort(404)
return view(*args, **kwargs)
return decorated
def cloud_edition_billing_paid_plan_required[**P, R](view: Callable[P, R]) -> Callable[P, R]:
@wraps(view)
def decorated(*args: P.args, **kwargs: P.kwargs):
_, current_tenant_id = current_account_with_tenant()
billing_info = BillingService.get_info(current_tenant_id, exclude_vector_space=True)
if not billing_info["enabled"] or billing_info["subscription"]["plan"] not in (
CloudPlan.PROFESSIONAL,
CloudPlan.TEAM,
):
abort(403, "This feature requires a paid plan.")
return view(*args, **kwargs)
return decorated
def cloud_edition_billing_resource_check[**P, R](resource: str) -> Callable[[Callable[P, R]], Callable[P, R]]:
def interceptor(view: Callable[P, R]):
@wraps(view)
def decorated(*args: P.args, **kwargs: P.kwargs):
_, current_tenant_id = current_account_with_tenant()
if resource == "vector_space":
if dify_config.DEPLOYMENT_EDITION != DeploymentEdition.CLOUD:
return view(*args, **kwargs)
vector_space = FeatureService.get_vector_space(current_tenant_id)
if 0 < vector_space.limit <= vector_space.size:
abort(
403,View on GitHub (pinned to ef8544b173)
Solutions
- Upgrade the workspace to a PROFESSIONAL or TEAM plan.
- Verify `BillingService` is correctly wired and returning `enabled=true` for the tenant.
- Gate the paid feature in the UI behind the plan flag from `/system-features`.
- If you believe billing is misconfigured, confirm the billing service connection and tenant subscription state.
Example fix
// before // free-plan tenant calls paid-only endpoint -> 403 // after // upgrade plan, or gate UI: if (features.billing.subscription.plan !== 'professional' && !== 'team') hideFeature()
Defensive patterns
Strategy: validation
Validate before calling
from services.billing_service import BillingService
_, tenant_id = current_account_with_tenant()
info = BillingService.get_info(tenant_id, exclude_vector_space=True)
plan = info["subscription"]["plan"]
def on_paid_plan() -> bool:
return info["enabled"] and plan in (CloudPlan.PROFESSIONAL, CloudPlan.TEAM)
if not on_paid_plan():
# do not call paid-only route
... Type guard
PAID = {"professional", "team"}
def is_paid_plan(plan: str | None) -> bool:
return (plan or "").lower() in PAID Try / catch
try:
resp = client.get("/paid-only-route")
except HTTPError as err:
if err.response.status_code == 403:
# show upgrade CTA
...
raise Prevention
- Upgrade to PROFESSIONAL/TEAM for paid-only features.
- Gate paid UI on the plan flag from /system-features.
- Verify BillingService returns enabled=true for the tenant.
- Refresh subscription state after plan changes.
When it happens
Trigger: Calling any route wrapped with `@cloud_edition_billing_paid_plan_required` from a tenant on the free/starter plan, with billing disabled, or with no subscription.
Common situations: Free-plan tenant hitting a paid-only feature (e.g. advanced model/analytics); trial expired; sandbox workspace without a paid subscription; billing service misconfigured so `enabled` reads false.
Related errors
- account_in_freeze
- account_in_freeze
- Trial app feature is not enabled.
- The number of members has reached the limit of your subscrip
- The number of apps has reached the limit of your subscriptio
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/b93cb056ff2852a8.
Report an issue: GitHub.