Significant-Gravitas/AutoGPT · error · HTTPException

success_url and cancel_url must match the platform frontend

Error message

success_url and cancel_url must match the platform frontend origin

What it means

Raised (422) by update_subscription_tier when _validate_checkout_redirect_url rejects request.success_url or request.cancel_url. The validator only accepts URLs whose origin matches the configured frontend/platform base origin, which prevents an attacker from supplying a success_url pointing at a phishing page that mimics a completed payment.

Source

Thrown at autogpt_platform/backend/backend/api/features/v1.py:1325

    # actionable error instead of the misleading "must match the platform
    # frontend origin" 422 that _validate_checkout_redirect_url would otherwise
    # produce when `allowed` is empty.
    if not (settings.config.frontend_base_url or settings.config.platform_base_url):
        logger.error(
            "update_subscription_tier: neither frontend_base_url nor "
            "platform_base_url is configured; cannot validate checkout redirect URLs"
        )
        raise HTTPException(
            status_code=503,
            detail=(
                "Payment redirect URLs cannot be validated: "
                "frontend_base_url or platform_base_url must be set on the server."
            ),
        )
    if not _validate_checkout_redirect_url(
        request.success_url
    ) or not _validate_checkout_redirect_url(request.cancel_url):
        raise HTTPException(
            status_code=422,
            detail="success_url and cancel_url must match the platform frontend origin",
        )
    try:
        url = await create_subscription_checkout(
            user_id=user_id,
            tier=tier,
            success_url=request.success_url,
            cancel_url=request.cancel_url,
            billing_cycle=request.billing_cycle,
            datafast_visitor_id=x_datafast_visitor_id,
            datafast_session_id=x_datafast_session_id,
        )
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except stripe.StripeError as e:
        logger.exception(
            "Stripe error creating checkout session for user %s: %s", user_id, e

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Send success_url and cancel_url whose scheme+host exactly match the server-configured frontend_base_url (only path/query may differ).
  2. If the mismatch is legitimate (new domain, env change), update frontend_base_url/platform_base_url on the backend to match where the frontend actually runs.
  3. Check for scheme mismatch (http vs https) and stray ports — origin comparison includes both.

Example fix

// before
const res = await api.upgradeTier({
  success_url: `https://old-domain.example/success`,
  cancel_url: `https://old-domain.example/cancel`,
});

// after — build from the same origin the app is served from
const res = await api.upgradeTier({
  success_url: `${window.location.origin}/success`,
  cancel_url: `${window.location.origin}/cancel`,
});
Defensive patterns

Strategy: validation

Validate before calling

function validRedirect(url: string, base: string): boolean {
  try { return new URL(url).origin === new URL(base).origin; }
  catch { return false; }
}
const base = appConfig.frontendBaseUrl;
if (!validRedirect(successUrl, base) || !validRedirect(cancelUrl, base)) {
  throw new Error('Redirect URLs must share the platform origin');
}

Type guard

const isSameOrigin = (u: string, base: string) => {
  try { return new URL(u).origin === new URL(base).origin; } catch { return false; }
};

Try / catch

catch (e) { if (e.response?.status === 422 && /frontend origin/.test(e.response.data.detail)) { rebuildRedirectsFromLocationOrigin(); } else throw e; }

Prevention

When it happens

Trigger: Calling the subscription checkout endpoint with a success_url or cancel_url whose scheme/host differs from the configured frontend_base_url/platform_base_url origin — e.g. success_url=https://evil.example/done, or a correct host on http:// while the config origin is https://, or a URL with a typo'd subdomain.

Common situations: Frontend deployed on a new domain while the backend still has the old base URL configured; local frontend on http://localhost:3000 but backend configured with the production origin (or vice versa); clients constructing redirect URLs from window.location while behind a proxy that rewrites the host.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/1a6052445d1d6d39. Report an issue: GitHub.