Skip to content

Self-hosted: 400 error on /v1/teams — unguarded billing.listOrganization() calls query non-existent 'platform' attribute #2835

@Lokeninfinitypoint

Description

@Lokeninfinitypoint

Bug Description

On self-hosted Appwrite 1.8.1 with Console 7.5.7, the organizations page (/console/account/organizations) returns a 400 Bad Request error:

AppwriteException: Invalid `queries` param: Invalid query: Attribute not found in schema: platform

The console sends:

GET /v1/teams?queries[0]=offset(0)&queries[1]=limit(6)&queries[2]=orderDesc("")&queries[3]=equal("platform","appwrite")
→ 400 Bad Request

The platform attribute does not exist in the self-hosted teams collection schema.

Root Cause

Two functions in BrayF0lC.js (billing utilities chunk) call billing.listOrganization() without checking isCloud:

  1. XL() — missingPaymentMethod check
// No isCloud guard!
async function XL() {
  const e = await sdk.billing.listOrganization([
    Query.notEqual("billingPlan", FREE),
    Query.isNull("paymentMethodId"),
    Query.isNull("backupPaymentMethodId"),
    Query.equal("platform", Platform.Appwrite)  // ← fails on self-hosted
  ]);
  // ...shows missingPaymentMethod banner
}
  1. JL() — newDevUpgradePro check
// No isCloud guard!
async function JL(e) {
  (await sdk.billing.listOrganization([
    Query.notEqual("billingPlan", FREE)  // ← also fails (billingPlan doesn't exist)
  ]))?.total
  // ...
}

Most other billing functions correctly guard with isCloud, for example HL():

async function HL(e, t) {
  if (!isCloud || !e) return;  // ✅ Correct guard
  // ...billing logic
}

The ternary patterns on other pages also correctly guard:

isCloud 
  ? await sdk.billing.listOrganization([Query.equal("platform", Platform.Appwrite)]) 
  : await sdk.teams.list()  // ✅ Correct fallback

Environment

  • Appwrite Server: 1.8.1 (Docker: appwrite/appwrite:1.8.1)
  • Appwrite Console: 7.5.7 (Docker: appwrite/console:7.5.7)
  • PUBLIC_CONSOLE_MODE: self-hosted (correctly set in env.js)
  • Browser: Chrome 144 (macOS)

Expected Behavior

On self-hosted installations, XL() and JL() should either:

  • Check isCloud before calling billing.listOrganization(), or
  • Be wrapped in a try/catch that silently handles the failure

Workaround

Added 'platform' to the ALLOWED_ATTRIBUTES array in Teams.php query validator, added platform column + index to the MariaDB _console_teams table, and added the attribute to the PHP collections config.

Suggested Fix

Add isCloud guard to both functions, matching the pattern already used in HL():

async function XL() {
  if (!isCloud) return;  // ← Add this
  // ...existing billing logic
}

async function JL(e) {
  if (!isCloud) return;  // ← Add this
  // ...existing billing logic
}

Reproduction Steps

  1. Install self-hosted Appwrite 1.8.1 with Console 7.5.7
  2. Set PUBLIC_CONSOLE_MODE=self-hosted
  3. Log into the console
  4. Navigate to Account → Organizations
  5. Open browser DevTools → Network tab
  6. See 400 error on /v1/teams with equal("platform","appwrite") query

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions