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
- Set the url to the exact frontend origin the backend is configured to trust (scheme, host, and port must all match an allowed origin).
- 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.
- 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.
- 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
- Build action links from a single configured frontend base URL constant.
- Keep backend trusted-origins env in sync with every environment that sends mail.
- Test scheme/host/port exactly — origin matching is strict.
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
- Search query must be at least 3 characters.
- Picker tokens are not available for provider '{provider.valu
- Username mismatch: authenticated as a different user
- Invalid signature
- Skill content rejected by virus scan
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/6365c19fdd4d7cf4.
Report an issue: GitHub.