langgenius/dify · error · AlreadyActivateError
already_activate
already_activate
Error message
Auth Token is invalid or account already activated, please check again.
What it means
Raised as AlreadyActivateError (code 'already_activate', HTTP 400) by POST /activate when RegisterService.get_invitation_with_case_fallback returns None — the (workspace_id, email, token) triple does not match a pending invitation. Common when the token was already consumed, expired, or never existed.
Source
Thrown at api/controllers/console/auth/activate.py:157
"Account activated successfully",
console_ns.models[ActivationResponse.__name__],
)
@console_ns.response(400, "Already activated or invalid token")
@model_validate(ActivatePayload)
def post(self, req_data: ActivatePayload):
"""Accept an invitation without letting an existing session act for another account.
Token-only activation remains available for legacy clients. When the request already
carries a console session, that session must belong to the account encoded in the
invitation before the token is consumed or tenant membership is changed.
"""
normalized_request_email = req_data.email.lower() if req_data.email else None
invitation = RegisterService.get_invitation_with_case_fallback(
req_data.workspace_id, req_data.email, req_data.token, session=db.session()
)
if invitation is None:
raise AlreadyActivateError()
account = invitation["account"]
if extract_access_token(request):
current_account, _ = current_account_with_tenant()
if current_account.id != account.id:
raise InvitationAccountMismatchError()
if dify_config.DEPLOYMENT_EDITION == DeploymentEdition.CLOUD and BillingService.is_email_in_freeze(
account.email
):
raise AccountInFreezeError()
tenant = invitation["tenant"]
raw_role = invitation["data"].get("role")
try:
role = TenantAccountRole(raw_role) if raw_role else TenantAccountRole.NORMAL
except ValueError:
role = TenantAccountRole.NORMALView on GitHub (pinned to ef8544b173)
Solutions
- Request a fresh invitation/activation email so a new token is issued.
- If already activated, simply sign in instead of re-using the activation link.
- Ensure the email submitted matches the invited email exactly (the service does a case-insensitive fallback, but typos in the local part still fail).
- Confirm workspace_id in the payload matches the inviting workspace.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await post('/activate', { workspace_id, email, token });
} catch (e) {
if (e.code === 'already_activate') {
// prompt: 'try signing in, or request a new invitation'
} else { throw e; }
} Prevention
- Treat activation links as single-use; don't click twice.
- If the link is old, request a fresh invitation rather than retrying.
- Sign in directly if the account is already active.
When it happens
Trigger: POST /console/api/activate with a token that has already been used, has expired, was revoked, or doesn't match the workspace_id/email pair. Also when email case does not match any stored invitation.
Common situations: Clicking an activation link twice (second click finds the token revoked); expired invitation; user changed email case; invitation was resent and the old token was invalidated; stale link from an old email.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/ab72794d935b266c.
Report an issue: GitHub.