Significant-Gravitas/AutoGPT · error · HTTPException

url must point at a trusted frontend origin.

Error message

url must point at a trusted frontend origin.

What it means

A 400 from the service-token-authenticated transactional email endpoint: the url in the request body does not pass _url_origin_allowed(), i.e. its origin (scheme+host+port) is not in the configured set of trusted frontend origins. The check exists because the url is embedded in the email body as a link, and an arbitrary origin would let callers phish users with the platform's own mail sender.

Source

Thrown at autogpt_platform/backend/backend/api/features/auth_email/routes.py:74

@auth_email_router.post(
    "/send",
    status_code=status.HTTP_204_NO_CONTENT,
    dependencies=[Security(requires_auth_email_service)],
    summary="Send a Better Auth transactional email via the backend mailer",
    # Without an explicit id the generated client name is derived from the
    # summary, which produces an unreadable mouthful.
    operation_id="sendAuthTransactionalEmail",
    responses={
        400: {"description": "url does not point at a trusted frontend origin"},
        403: {"description": "Service token is missing the required scope"},
        503: {"description": "Service-token verification is not configured"},
    },
    # The tag comes from the router include in rest_api.py; repeating it here
    # duplicates it in the generated spec.
)
async def send_auth_email(request: AuthEmailRequest) -> None:
    if not _url_origin_allowed(request.url):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="url must point at a trusted frontend origin.",
        )

    subject = _SUBJECTS[request.type]
    action = _ACTIONS[request.type]
    # Escape the (host-validated) URL before embedding it in HTML — a path or
    # query on an allowed host could still carry markup-breaking characters.
    safe_url = html.escape(request.url, quote=True)
    body = (
        f"<p>Click the link below to {action} for the AutoGPT Platform:</p>"
        f'<p><a href="{safe_url}">{safe_url}</a></p>'
        "<p>If you didn't request this, you can safely ignore this email.</p>"
    )

    # The blocking RPC to the notification service runs off the event loop; a
    # delivery failure there surfaces as a 5xx so a misconfigured mailer fails
    # loudly instead of dropping the auth email.

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Set the url to the exact frontend origin the backend is configured to trust (scheme, host, and port must all match an allowed origin).
  2. Check the backend's trusted-origins config/env (e.g. APP_BACKEND_CORS_ORIGINS or equivalent) and add the origin you actually send from, then redeploy/restart.
  3. If running locally, point the url at the local frontend origin and ensure that origin is in the backend's allowed list for the dev environment.
  4. Verify no stray path/port mismatch: the origin check runs before path escaping, so fix the scheme://host:port portion first.

Example fix

# before
{"type": "reset_password", "url": "http://localhost:3000/reset?token=..."}  # origin not trusted in prod

# after
{"type": "reset_password", "url": "https://app.example.com/reset?token=..."}  # matches configured trusted origin
Defensive patterns

Strategy: validation

Validate before calling

const allowed = new Set(trustedOrigins); // from backend config
const origin = new URL(link).origin;
if (!allowed.has(origin)) throw new Error(`untrusted origin: ${origin}`);
await sendAuthEmail({type, url: link});

Type guard

function isTrustedOrigin(url: string, allowed: string[]): boolean {
  try { return allowed.includes(new URL(url).origin); } catch { return false; }
}

Prevention

When it happens

Trigger: POST to the auth email route with a url whose host is not in APP_BACKEND_CORS_ORIGINS / the trusted-frontend-origins config (e.g. a staging URL when the backend only trusts prod, http:// when only https origins are listed, or a completely different domain).

Common situations: Misconfigured FRONTEND_BASE_URL / allowed-origins env var in the environment sending the email; a local dev frontend at http://localhost:3000 while the backend only trusts the deployed origin; a URL with a typo'd hostname or wrong port; constructing the reset/verify link server-side from the wrong base URL.

Related errors


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