Ecto.Changeset.add_error allows Ecto.Changeset.add_error to pass any atom as a key, it does not have to be a field of this model. You can add an error to :base as follows:
add_error(changeset, :base, "email or password is invalid")
and then in your template follow these steps:
<%= error_tag f, :base %>
or (after checking for an error):
<%= @changeset.errors[:base] %>
Another option for your use is to add an error on both :email and :password
changeset |> add_error(:email, "email or password is invalid") |> add_error(:password, "email or password is invalid")
source share