discourse/discourse · warning · ActiveRecord::RecordNotSaved

invite.not_matching_email

Error message

invite.not_matching_email

What it means

InviteRedeemer#can_redeem_invite? raises RecordNotSaved with invite.not_matching_email when the invite was issued to a specific email but the redeeming user's email (or supplied email) does not match per invite.email_matches?.

Source

Thrown at app/models/invite_redeemer.rb:192

  private

  def can_redeem_invite?
    return false if !invite.redeemable?
    return false if email.blank?

    # Invite scoped to email has already been redeemed by anyone.
    return false if invite.is_email_invite? && InvitedUser.exists?(invite_id: invite.id)

    # The email will be present for either an invite link (where the user provides
    # us the email manually) or for an invite scoped to an email, where we
    # prefill the email and do not let the user modify it.
    #
    # Note that an invite link can also have a domain scope which must be checked.
    email_to_check = redeeming_user&.email || email

    if invite.email.present? && !invite.email_matches?(email_to_check)
      raise ActiveRecord::RecordNotSaved.new(I18n.t("invite.not_matching_email"))
    end

    if invite.domain.present? && !invite.domain_matches?(email_to_check)
      raise ActiveRecord::RecordNotSaved.new(I18n.t("invite.domain_not_allowed"))
    end

    # Anon user is trying to redeem an invitation, if an existing user already
    # redeemed it then we cannot redeem now.
    redeeming_user ||= User.where(admin: false, staged: false).find_by_email(email)
    if redeeming_user.present? &&
         InvitedUser.exists?(user_id: redeeming_user.id, invite_id: invite.id)
      raise Invite::UserExists.new(I18n.t("invite.existing_user_already_redemeed"))
    end

    true
  end

  # Note that the invited_user is returned by #redeemed, so other places

View on GitHub (pinned to 1b2d7253e8)

Solutions

  1. Redeem the invite with the exact email it was sent to (or logged out so the email field applies)
  2. Ask the inviter to generate a new invite for the new address
  3. For broad invites, invite by domain instead of a fixed email
Defensive patterns

Strategy: validation

Validate before calling

email_to_check = current_user&.email || params[:email]
return mismatch_page if invite.email.present? && !invite.email_matches?(email_to_check)

Try / catch

rescue ActiveRecord::RecordNotSaved => e; show invite.not_matching_email message

Prevention

When it happens

Trigger: Redeeming an emailed invite link with a different account, or passing an email query param that differs from the invited address.

Common situations: User forwards an invite to a colleague; redeems while logged in as another account; typo in the email param.

Related errors


AI-assisted analysis of discourse/discourse@1b2d7253e8 (2026-08-26). Data as JSON: /api/errors/cb501ef3f950bb62. Report an issue: GitHub.