langgenius/dify · error · BadRequest

Invalid partner_key

Error message

Invalid partner_key

What it means

Flask BadRequest (HTTP 400) raised at billing.py:96 in the partner-tenants PUT handler when base64.b64decode(partner_key).decode('utf-8') throws (or req_data.click_id access throws) inside the try block. partner_key is the URL path parameter; if it is not valid base64 or not valid UTF-8 after decoding, the broad `except Exception` fires and reports 'Invalid partner_key'. The endpoint is Cloud-only (@only_edition_cloud).

Source

Thrown at api/controllers/console/billing/billing.py:96

class PartnerTenants(Resource):
    @console_ns.doc("sync_partner_tenants_bindings")
    @console_ns.doc(description="Sync partner tenants bindings")
    @console_ns.doc(params={"partner_key": "Partner key"})
    @console_ns.expect(console_ns.models[PartnerTenantsPayload.__name__])
    @console_ns.response(200, "Tenants synced to partner successfully", console_ns.models[BillingResponse.__name__])
    @console_ns.response(400, "Invalid partner information")
    @setup_required
    @login_required
    @account_initialization_required
    @only_edition_cloud
    @with_current_user
    @model_validate(PartnerTenantsPayload)
    def put(self, req_data: PartnerTenantsPayload, current_user: Account, partner_key: str):
        try:
            click_id = req_data.click_id
            decoded_partner_key = base64.b64decode(partner_key).decode("utf-8")
        except Exception:
            raise BadRequest("Invalid partner_key")

        if not click_id or not decoded_partner_key or not current_user.id:
            raise BadRequest("Invalid partner information")

        return BillingService.sync_partner_tenants_bindings(current_user.id, decoded_partner_key, click_id)

View on GitHub (pinned to ef8544b173)

Solutions

  1. Send the partner_key exactly as issued, as standard base64, URL-safe in the path (encode any '+/=' appropriately).
  2. Verify the key decodes to UTF-8 before sending: `base64.b64decode(key).decode('utf-8')` should succeed locally.
  3. If the key was rotated, obtain the new partner_key from billing/partner admin.
  4. Narrow the except clause (catch binascii.Error / UnicodeDecodeError specifically) so unrelated bugs are not masked.

Example fix

// before
try:
    click_id = req_data.click_id
    decoded_partner_key = base64.b64decode(partner_key).decode("utf-8")
except Exception:
    raise BadRequest("Invalid partner_key")
// after
import binascii
try:
    click_id = req_data.click_id
    decoded_partner_key = base64.b64decode(partner_key, validate=True).decode("utf-8")
except (binascii.Error, UnicodeDecodeError, ValueError):
    raise BadRequest("Invalid partner_key")
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate partner_key is base64 and decodes to UTF-8 before the PUT.
function decodePartnerKey(key: string): string {
  const decoded = atob(key);
  if (!decoded) throw new Error('partner_key decodes to empty');
  return decoded;
}
const decoded = decodePartnerKey(partnerKey);

Type guard

function isBase64(s: string): boolean {
  return /^[A-Za-z0-9+/_-]+={0,2}$/.test(s) && (() => { try { atob(s); return true; } catch { return false; } })();
}

Try / catch

try {
  await putPartnerTenants(partnerKey, clickId);
} catch (e) {
  if (/Invalid partner_key/i.test(e.message)) { refreshPartnerKey(); } else throw e;
}

Prevention

When it happens

Trigger: PUT /console/api/billing/partner/tenants/<partner_key> on Cloud edition with a partner_key that is malformed base64, truncated, URL-mangled, or contains non-UTF-8 bytes. Any exception in the try (including a model field access error) maps to this message.

Common situations: Partner integration sends a raw key instead of its base64 encoding; URL-encoding double-escapes the key; or a stale/rotated partner key that no longer decodes. The broad `except Exception` also hides unexpected bugs as 'Invalid partner_key'.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/926655d9c56a0e4c. Report an issue: GitHub.