[GH-ISSUE #5621] send-verification-email always results in YOU_CAN_ONLY_SEND_A_VERIFICATION_EMAIL_TO_AN_UNVERIFIED_EMAIL #27628

Closed
opened 2026-04-17 18:44:08 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @bnssoftware on GitHub (Oct 27, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/5621

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create new user with email and password and email verification enabled
  2. As an admin, call the /api/auth/send-verification-email enpoint with that user's email address
  3. YOU_CAN_ONLY_SEND_A_VERIFICATION_EMAIL_TO_AN_UNVERIFIED_EMAIL is raised, even though the email address has not yet been verified (as evidenced by the emailVerified field being false in the database for that user)

Current vs. Expected behavior

Expected behavior is to send a new verification email if user is not yet verified

What version of Better Auth are you using?

1.3.0

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 11 Home",
    "release": "10.0.26200",
    "cpuCount": 12,
    "cpuModel": "12th Gen Intel(R) Core(TM) i5-1235U",
    "totalMemory": "63.65 GB",
    "freeMemory": "47.97 GB"
  },
  "node": {
    "version": "v24.5.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.5.2"
  },
  "frameworks": [
    {
      "name": "hono",
      "version": "^4.7.8"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.13.1"
    }
  ],
  "betterAuth": {
    "version": "^1.3.28",
    "config": {
      "database": {
        "_events": {},
        "_eventsCount": 0,
        "options": {
          "connectionString": "[REDACTED]",
          "max": 10,
          "min": 0,
          "maxUses": null,
          "allowExitOnIdle": false,
          "maxLifetimeSeconds": 0,
          "idleTimeoutMillis": 10000
        },
        "_clients": [],
        "_idle": [],
        "_expired": {},
        "_pendingQueue": [],
        "ending": false,
        "ended": false
      },
      "emailAndPassword": {
        "enabled": true,
        "requireEmailVerification": true
      },
      "emailVerification": {},
      "plugins": [
        {
          "name": "admin",
          "config": {
            "id": "admin",
            "hooks": {
              "after": [
                {}
              ]
            },
            "endpoints": {},
            "$ERROR_CODES": {
              "FAILED_TO_CREATE_USER": "Failed to create user",
              "USER_ALREADY_EXISTS": "User already exists.",
              "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL": "User already exists. Use another email.",
              "YOU_CANNOT_BAN_YOURSELF": "You cannot ban yourself",
              "YOU_ARE_NOT_ALLOWED_TO_CHANGE_USERS_ROLE": "You are not allowed to change users role",
              "YOU_ARE_NOT_ALLOWED_TO_CREATE_USERS": "You are not allowed to create users",
              "YOU_ARE_NOT_ALLOWED_TO_LIST_USERS": "You are not allowed to list users",
              "YOU_ARE_NOT_ALLOWED_TO_LIST_USERS_SESSIONS": "You are not allowed to list users sessions",
              "YOU_ARE_NOT_ALLOWED_TO_BAN_USERS": "You are not allowed to ban users",
              "YOU_ARE_NOT_ALLOWED_TO_IMPERSONATE_USERS": "You are not allowed to impersonate users",
              "YOU_ARE_NOT_ALLOWED_TO_REVOKE_USERS_SESSIONS": "You are not allowed to revoke users sessions",
              "YOU_ARE_NOT_ALLOWED_TO_DELETE_USERS": "You are not allowed to delete users",
              "YOU_ARE_NOT_ALLOWED_TO_SET_USERS_PASSWORD": "[REDACTED]",
              "BANNED_USER": "You have been banned from this application",
              "YOU_ARE_NOT_ALLOWED_TO_GET_USER": "You are not allowed to get user",
              "NO_DATA_TO_UPDATE": "No data to update",
              "YOU_ARE_NOT_ALLOWED_TO_UPDATE_USERS": "You are not allowed to update users",
              "YOU_CANNOT_REMOVE_YOURSELF": "You cannot remove yourself"
            },
            "schema": {
              "user": {
                "fields": {
                  "role": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "banned": {
                    "type": "boolean",
                    "defaultValue": false,
                    "required": false,
                    "input": false
                  },
                  "banReason": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "banExpires": {
                    "type": "date",
                    "required": false,
                    "input": false
                  }
                }
              },
              "session": {
                "fields": {
                  "impersonatedBy": {
                    "type": "string",
                    "required": false
                  }
                }
              }
            },
            "options": {
              "defaultRole": "user",
              "adminRoles": [
                "admin",
                "superadmin"
              ],
              "impersonationSessionDuration": 3600
            }
          }
        },
        {
          "name": "organization",
          "config": {
            "id": "organization",
            "endpoints": {},
            "schema": {
              "organization": {
                "fields": {
                  "name": {
                    "type": "string",
                    "required": true,
                    "sortable": true
                  },
                  "slug": {
                    "type": "string",
                    "required": true,
                    "unique": true,
                    "sortable": true
                  },
                  "logo": {
                    "type": "string",
                    "required": false
                  },
                  "createdAt": {
                    "type": "date",
                    "required": true
                  },
                  "metadata": {
                    "type": "string",
                    "required": false
                  }
                }
              },
              "member": {
                "fields": {
                  "organizationId": {
                    "type": "string",
                    "required": true,
                    "references": {
                      "model": "organization",
                      "field": "id"
                    }
                  },
                  "userId": {
                    "type": "string",
                    "required": true,
                    "references": {
                      "model": "user",
                      "field": "id"
                    }
                  },
                  "role": {
                    "type": "string",
                    "required": true,
                    "sortable": true,
                    "defaultValue": "member"
                  },
                  "createdAt": {
                    "type": "date",
                    "required": true
                  }
                }
              },
              "invitation": {
                "fields": {
                  "organizationId": {
                    "type": "string",
                    "required": true,
                    "references": {
                      "model": "organization",
                      "field": "id"
                    }
                  },
                  "email": {
                    "type": "string",
                    "required": true,
                    "sortable": true
                  },
                  "role": {
                    "type": "string",
                    "required": false,
                    "sortable": true
                  },
                  "status": {
                    "type": "string",
                    "required": true,
                    "sortable": true,
                    "defaultValue": "pending"
                  },
                  "expiresAt": {
                    "type": "date",
                    "required": true
                  },
                  "inviterId": {
                    "type": "string",
                    "references": {
                      "model": "user",
                      "field": "id"
                    },
                    "required": true
                  }
                }
              },
              "session": {
                "fields": {
                  "activeOrganizationId": {
                    "type": "string",
                    "required": false
                  }
                }
              }
            },
            "$Infer": {
              "Organization": {},
              "Invitation": {},
              "Member": {},
              "Team": {},
              "TeamMember": {},
              "ActiveOrganization": {}
            },
            "$ERROR_CODES": {
              "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_ORGANIZATION": "You are not allowed to create a new organization",      
              "YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS": "You have reached the maximum number of organizations",
              "ORGANIZATION_ALREADY_EXISTS": "Organization already exists",
              "ORGANIZATION_NOT_FOUND": "Organization not found",
              "USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION": "User is not a member of the organization",
              "YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_ORGANIZATION": "You are not allowed to update this organization",        
              "YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_ORGANIZATION": "You are not allowed to delete this organization",        
              "NO_ACTIVE_ORGANIZATION": "No active organization",
              "USER_IS_ALREADY_A_MEMBER_OF_THIS_ORGANIZATION": "User is already a member of this organization",
              "MEMBER_NOT_FOUND": "Member not found",
              "ROLE_NOT_FOUND": "Role not found",
              "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_TEAM": "You are not allowed to create a new team",
              "TEAM_ALREADY_EXISTS": "Team already exists",
              "TEAM_NOT_FOUND": "Team not found",
              "YOU_CANNOT_LEAVE_THE_ORGANIZATION_AS_THE_ONLY_OWNER": "You cannot leave the organization as the only owner",
              "YOU_CANNOT_LEAVE_THE_ORGANIZATION_WITHOUT_AN_OWNER": "You cannot leave the organization without an owner",  
              "YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_MEMBER": "You are not allowed to delete this member",
              "YOU_ARE_NOT_ALLOWED_TO_INVITE_USERS_TO_THIS_ORGANIZATION": "You are not allowed to invite users to this organization",
              "USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION": "User is already invited to this organization",
              "INVITATION_NOT_FOUND": "Invitation not found",
              "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION": "You are not the recipient of the invitation",
              "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION": "Email verification required before accepting or rejecting invitation",
              "YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION": "You are not allowed to cancel this invitation",
              "INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION": "Inviter is no longer a member of the organization",    
              "YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE": "You are not allowed to invite a user with this role",  
              "FAILED_TO_RETRIEVE_INVITATION": "Failed to retrieve invitation",
              "YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_TEAMS": "You have reached the maximum number of teams",
              "UNABLE_TO_REMOVE_LAST_TEAM": "Unable to remove last team",
              "YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER": "You are not allowed to update this member",
              "ORGANIZATION_MEMBERSHIP_LIMIT_REACHED": "Organization membership limit reached",
              "YOU_ARE_NOT_ALLOWED_TO_CREATE_TEAMS_IN_THIS_ORGANIZATION": "You are not allowed to create teams in this organization",
              "YOU_ARE_NOT_ALLOWED_TO_DELETE_TEAMS_IN_THIS_ORGANIZATION": "You are not allowed to delete teams in this organization",
              "YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_TEAM": "You are not allowed to update this team",
              "YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_TEAM": "You are not allowed to delete this team",
              "INVITATION_LIMIT_REACHED": "Invitation limit reached",
              "TEAM_MEMBER_LIMIT_REACHED": "Team member limit reached",
              "USER_IS_NOT_A_MEMBER_OF_THE_TEAM": "User is not a member of the team",
              "YOU_CAN_NOT_ACCESS_THE_MEMBERS_OF_THIS_TEAM": "You are not allowed to list the members of this team",       
              "YOU_DO_NOT_HAVE_AN_ACTIVE_TEAM": "You do not have an active team",
              "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_TEAM_MEMBER": "You are not allowed to create a new member",
              "YOU_ARE_NOT_ALLOWED_TO_REMOVE_A_TEAM_MEMBER": "You are not allowed to remove a team member",
              "YOU_ARE_NOT_ALLOWED_TO_ACCESS_THIS_ORGANIZATION": "You are not allowed to access this organization as an owner",
              "YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION": "You are not a member of this organization",
              "MISSING_AC_INSTANCE": "Dynamic Access Control requires a pre-defined ac instance on the server auth plugin. Read server logs for more information",
              "YOU_MUST_BE_IN_AN_ORGANIZATION_TO_CREATE_A_ROLE": "You must be in an organization to create a role",        
              "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_ROLE": "You are not allowed to create a role",
              "YOU_ARE_NOT_ALLOWED_TO_UPDATE_A_ROLE": "You are not allowed to update a role",
              "YOU_ARE_NOT_ALLOWED_TO_DELETE_A_ROLE": "You are not allowed to delete a role",
              "YOU_ARE_NOT_ALLOWED_TO_READ_A_ROLE": "You are not allowed to read a role",
              "YOU_ARE_NOT_ALLOWED_TO_LIST_A_ROLE": "You are not allowed to list a role",
              "YOU_ARE_NOT_ALLOWED_TO_GET_A_ROLE": "You are not allowed to get a role",
              "TOO_MANY_ROLES": "This organization has too many roles",
              "INVALID_RESOURCE": "The provided permission includes an invalid resource",
              "ROLE_NAME_IS_ALREADY_TAKEN": "That role name is already taken",
              "CANNOT_DELETE_A_PRE_DEFINED_ROLE": "Cannot delete a pre-defined role"
            },
            "options": {
              "allowUserToCreateOrganization": true
            }
          }
        },
        {
          "name": "two-factor",
          "config": {
            "id": "two-factor",
            "endpoints": {},
            "options": {
              "issuer": "Platform Login",
              "otpOptions": {}
            },
            "hooks": {
              "after": [
                {}
              ]
            },
            "schema": {
              "user": {
                "fields": {
                  "twoFactorEnabled": {
                    "type": "boolean",
                    "required": false,
                    "defaultValue": false,
                    "input": false
                  }
                }
              },
              "twoFactor": {
                "fields": {
                  "secret": {
                    "type": "string",
                    "required": true,
                    "returned": false
                  },
                  "backupCodes": {
                    "type": "string",
                    "required": true,
                    "returned": false
                  },
                  "userId": {
                    "type": "string",
                    "required": true,
                    "returned": false,
                    "references": {
                      "model": "user",
                      "field": "id"
                    }
                  }
                }
              }
            },
            "rateLimit": [
              {
                "window": 10,
                "max": 3
              }
            ],
            "$ERROR_CODES": {
              "OTP_NOT_ENABLED": "OTP not enabled",
              "OTP_HAS_EXPIRED": "OTP has expired",
              "TOTP_NOT_ENABLED": "TOTP not enabled",
              "TWO_FACTOR_NOT_ENABLED": "Two factor isn't enabled",
              "BACKUP_CODES_NOT_ENABLED": "Backup codes aren't enabled",
              "INVALID_BACKUP_CODE": "Invalid backup code",
              "INVALID_CODE": "Invalid code",
              "TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE": "Too many attempts. Please request a new code.",
              "INVALID_TWO_FACTOR_COOKIE": "Invalid two factor cookie"
            }
          }
        },
        {
          "name": "multi-session",
          "config": {
            "id": "multi-session",
            "endpoints": {},
            "hooks": {
              "after": [
                {},
                {}
              ]
            },
            "$ERROR_CODES": {
              "INVALID_SESSION_TOKEN": "[REDACTED]"
            }
          }
        },
        {
          "name": "last-login-method",
          "config": {
            "id": "last-login-method",
            "hooks": {
              "after": [
                {}
              ]
            }
          }
        },
        {
          "name": "api-key",
          "config": {
            "id": "api-key",
            "$ERROR_CODES": {
              "INVALID_METADATA_TYPE": "metadata must be an object or undefined",
              "REFILL_AMOUNT_AND_INTERVAL_REQUIRED": "refillAmount is required when refillInterval is provided",
              "REFILL_INTERVAL_AND_AMOUNT_REQUIRED": "refillInterval is required when refillAmount is provided",
              "USER_BANNED": "User is banned",
              "UNAUTHORIZED_SESSION": "Unauthorized or invalid session",
              "KEY_NOT_FOUND": "API Key not found",
              "KEY_DISABLED": "API Key is disabled",
              "KEY_EXPIRED": "API Key has expired",
              "USAGE_EXCEEDED": "API Key has reached its usage limit",
              "KEY_NOT_RECOVERABLE": "API Key is not recoverable",
              "EXPIRES_IN_IS_TOO_SMALL": "The expiresIn is smaller than the predefined minimum value.",
              "EXPIRES_IN_IS_TOO_LARGE": "The expiresIn is larger than the predefined maximum value.",
              "INVALID_REMAINING": "The remaining count is either too large or too small.",
              "INVALID_PREFIX_LENGTH": "The prefix length is either too large or too small.",
              "INVALID_NAME_LENGTH": "The name length is either too large or too small.",
              "METADATA_DISABLED": "Metadata is disabled.",
              "RATE_LIMIT_EXCEEDED": "Rate limit exceeded.",
              "NO_VALUES_TO_UPDATE": "No values to update.",
              "KEY_DISABLED_EXPIRATION": "Custom key expiration values are disabled.",
              "INVALID_API_KEY": "Invalid API key.",
              "INVALID_USER_ID_FROM_API_KEY": "The user id from the API key is invalid.",
              "INVALID_API_KEY_GETTER_RETURN_TYPE": "API Key getter returned an invalid key type. Expected string.",       
              "SERVER_ONLY_PROPERTY": "The property you're trying to set can only be set from the server auth instance only.",
              "FAILED_TO_UPDATE_API_KEY": "Failed to update API key",
              "NAME_REQUIRED": "API Key name is required."
            },
            "hooks": {
              "before": [
                {}
              ]
            },
            "endpoints": {},
            "schema": {
              "apikey": {
                "fields": {
                  "name": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "start": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "prefix": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "key": {
                    "type": "string",
                    "required": true,
                    "input": false
                  },
                  "userId": {
                    "type": "string",
                    "references": {
                      "model": "user",
                      "field": "id",
                      "onDelete": "cascade"
                    },
                    "required": true,
                    "input": false
                  },
                  "refillInterval": {
                    "type": "number",
                    "required": false,
                    "input": false
                  },
                  "refillAmount": {
                    "type": "number",
                    "required": false,
                    "input": false
                  },
                  "lastRefillAt": {
                    "type": "date",
                    "required": false,
                    "input": false
                  },
                  "enabled": {
                    "type": "boolean",
                    "required": false,
                    "input": false,
                    "defaultValue": true
                  },
                  "rateLimitEnabled": {
                    "type": "boolean",
                    "required": false,
                    "input": false,
                    "defaultValue": true
                  },
                  "rateLimitTimeWindow": {
                    "type": "number",
                    "required": false,
                    "input": false,
                    "defaultValue": 86400000
                  },
                  "rateLimitMax": {
                    "type": "number",
                    "required": false,
                    "input": false,
                    "defaultValue": 10
                  },
                  "requestCount": {
                    "type": "number",
                    "required": false,
                    "input": false,
                    "defaultValue": 0
                  },
                  "remaining": {
                    "type": "number",
                    "required": false,
                    "input": false
                  },
                  "lastRequest": {
                    "type": "date",
                    "required": false,
                    "input": false
                  },
                  "expiresAt": {
                    "type": "date",
                    "required": false,
                    "input": false
                  },
                  "createdAt": {
                    "type": "date",
                    "required": true,
                    "input": false
                  },
                  "updatedAt": {
                    "type": "date",
                    "required": true,
                    "input": false
                  },
                  "permissions": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "metadata": {
                    "type": "string",
                    "required": false,
                    "input": true,
                    "transform": {}
                  }
                }
              }
            }
          }
        },
        {
          "name": "oidc",
          "config": {
            "id": "oidc",
            "hooks": {
              "after": [
                {}
              ]
            },
            "endpoints": {},
            "schema": {
              "oauthApplication": {
                "modelName": "oauthApplication",
                "fields": {
                  "name": {
                    "type": "string"
                  },
                  "icon": {
                    "type": "string",
                    "required": false
                  },
                  "metadata": {
                    "type": "string",
                    "required": false
                  },
                  "clientId": {
                    "type": "string",
                    "unique": true
                  },
                  "clientSecret": {
                    "type": "string",
                    "required": false
                  },
                  "redirectURLs": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "disabled": {
                    "type": "boolean",
                    "required": false,
                    "defaultValue": false
                  },
                  "userId": {
                    "type": "string",
                    "required": false,
                    "references": {
                      "model": "user",
                      "field": "id",
                      "onDelete": "cascade"
                    }
                  },
                  "createdAt": {
                    "type": "date"
                  },
                  "updatedAt": {
                    "type": "date"
                  }
                }
              },
              "oauthAccessToken": {
                "modelName": "oauthAccessToken",
                "fields": {
                  "accessToken": {
                    "type": "string",
                    "unique": true
                  },
                  "refreshToken": {
                    "type": "string",
                    "unique": true
                  },
                  "accessTokenExpiresAt": {
                    "type": "date"
                  },
                  "refreshTokenExpiresAt": {
                    "type": "date"
                  },
                  "clientId": {
                    "type": "string",
                    "references": {
                      "model": "oauthApplication",
                      "field": "clientId",
                      "onDelete": "cascade"
                    }
                  },
                  "userId": {
                    "type": "string",
                    "required": false,
                    "references": {
                      "model": "user",
                      "field": "id",
                      "onDelete": "cascade"
                    }
                  },
                  "scopes": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "date"
                  },
                  "updatedAt": {
                    "type": "date"
                  }
                }
              },
              "oauthConsent": {
                "modelName": "oauthConsent",
                "fields": {
                  "clientId": {
                    "type": "string",
                    "references": {
                      "model": "oauthApplication",
                      "field": "clientId",
                      "onDelete": "cascade"
                    }
                  },
                  "userId": {
                    "type": "string",
                    "references": {
                      "model": "user",
                      "field": "id",
                      "onDelete": "cascade"
                    }
                  },
                  "scopes": {
                    "type": "string"
                  },
                  "createdAt": {
                    "type": "date"
                  },
                  "updatedAt": {
                    "type": "date"
                  },
                  "consentGiven": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        {
          "name": "open-api",
          "config": {
            "id": "open-api",
            "endpoints": {}
          }
        }
      ],
      "socialProviders": {
        "github": {
          "clientId": "",
          "clientSecret": "",
          "enabled": false
        },
        "google": {
          "clientId": "[REDACTED]",
          "clientSecret": "[REDACTED]",
          "enabled": true
        }
      },
      "session": {
        "expiresIn": 604800,
        "updateAge": 86400,
        "cookieCache": {
          "enabled": true,
          "maxAge": 300
        }
      },
      "user": {
        "additionalFields": {
          "emailVerified": {
            "type": "boolean",
            "required": false,
            "defaultValue": false
          }
        }
      },
      "advanced": {
        "database": {}
      },
      "trustedOrigins": [
        "http://localhost:3000",
        "http://localhost:5173",
        "http://localhost:4321"
      ],
      "baseURL": "http://localhost:3000",
      "secret": "[REDACTED]"
    }
  }
}

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @bnssoftware on GitHub (Oct 27, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/5621 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create new user with email and password and email verification enabled 2. As an admin, call the /api/auth/send-verification-email enpoint with that user's email address 3. YOU_CAN_ONLY_SEND_A_VERIFICATION_EMAIL_TO_AN_UNVERIFIED_EMAIL is raised, even though the email address has not yet been verified (as evidenced by the emailVerified field being false in the database for that user) ### Current vs. Expected behavior Expected behavior is to send a new verification email if user is not yet verified ### What version of Better Auth are you using? 1.3.0 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 11 Home", "release": "10.0.26200", "cpuCount": 12, "cpuModel": "12th Gen Intel(R) Core(TM) i5-1235U", "totalMemory": "63.65 GB", "freeMemory": "47.97 GB" }, "node": { "version": "v24.5.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.5.2" }, "frameworks": [ { "name": "hono", "version": "^4.7.8" } ], "databases": [ { "name": "pg", "version": "^8.13.1" } ], "betterAuth": { "version": "^1.3.28", "config": { "database": { "_events": {}, "_eventsCount": 0, "options": { "connectionString": "[REDACTED]", "max": 10, "min": 0, "maxUses": null, "allowExitOnIdle": false, "maxLifetimeSeconds": 0, "idleTimeoutMillis": 10000 }, "_clients": [], "_idle": [], "_expired": {}, "_pendingQueue": [], "ending": false, "ended": false }, "emailAndPassword": { "enabled": true, "requireEmailVerification": true }, "emailVerification": {}, "plugins": [ { "name": "admin", "config": { "id": "admin", "hooks": { "after": [ {} ] }, "endpoints": {}, "$ERROR_CODES": { "FAILED_TO_CREATE_USER": "Failed to create user", "USER_ALREADY_EXISTS": "User already exists.", "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL": "User already exists. Use another email.", "YOU_CANNOT_BAN_YOURSELF": "You cannot ban yourself", "YOU_ARE_NOT_ALLOWED_TO_CHANGE_USERS_ROLE": "You are not allowed to change users role", "YOU_ARE_NOT_ALLOWED_TO_CREATE_USERS": "You are not allowed to create users", "YOU_ARE_NOT_ALLOWED_TO_LIST_USERS": "You are not allowed to list users", "YOU_ARE_NOT_ALLOWED_TO_LIST_USERS_SESSIONS": "You are not allowed to list users sessions", "YOU_ARE_NOT_ALLOWED_TO_BAN_USERS": "You are not allowed to ban users", "YOU_ARE_NOT_ALLOWED_TO_IMPERSONATE_USERS": "You are not allowed to impersonate users", "YOU_ARE_NOT_ALLOWED_TO_REVOKE_USERS_SESSIONS": "You are not allowed to revoke users sessions", "YOU_ARE_NOT_ALLOWED_TO_DELETE_USERS": "You are not allowed to delete users", "YOU_ARE_NOT_ALLOWED_TO_SET_USERS_PASSWORD": "[REDACTED]", "BANNED_USER": "You have been banned from this application", "YOU_ARE_NOT_ALLOWED_TO_GET_USER": "You are not allowed to get user", "NO_DATA_TO_UPDATE": "No data to update", "YOU_ARE_NOT_ALLOWED_TO_UPDATE_USERS": "You are not allowed to update users", "YOU_CANNOT_REMOVE_YOURSELF": "You cannot remove yourself" }, "schema": { "user": { "fields": { "role": { "type": "string", "required": false, "input": false }, "banned": { "type": "boolean", "defaultValue": false, "required": false, "input": false }, "banReason": { "type": "string", "required": false, "input": false }, "banExpires": { "type": "date", "required": false, "input": false } } }, "session": { "fields": { "impersonatedBy": { "type": "string", "required": false } } } }, "options": { "defaultRole": "user", "adminRoles": [ "admin", "superadmin" ], "impersonationSessionDuration": 3600 } } }, { "name": "organization", "config": { "id": "organization", "endpoints": {}, "schema": { "organization": { "fields": { "name": { "type": "string", "required": true, "sortable": true }, "slug": { "type": "string", "required": true, "unique": true, "sortable": true }, "logo": { "type": "string", "required": false }, "createdAt": { "type": "date", "required": true }, "metadata": { "type": "string", "required": false } } }, "member": { "fields": { "organizationId": { "type": "string", "required": true, "references": { "model": "organization", "field": "id" } }, "userId": { "type": "string", "required": true, "references": { "model": "user", "field": "id" } }, "role": { "type": "string", "required": true, "sortable": true, "defaultValue": "member" }, "createdAt": { "type": "date", "required": true } } }, "invitation": { "fields": { "organizationId": { "type": "string", "required": true, "references": { "model": "organization", "field": "id" } }, "email": { "type": "string", "required": true, "sortable": true }, "role": { "type": "string", "required": false, "sortable": true }, "status": { "type": "string", "required": true, "sortable": true, "defaultValue": "pending" }, "expiresAt": { "type": "date", "required": true }, "inviterId": { "type": "string", "references": { "model": "user", "field": "id" }, "required": true } } }, "session": { "fields": { "activeOrganizationId": { "type": "string", "required": false } } } }, "$Infer": { "Organization": {}, "Invitation": {}, "Member": {}, "Team": {}, "TeamMember": {}, "ActiveOrganization": {} }, "$ERROR_CODES": { "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_ORGANIZATION": "You are not allowed to create a new organization", "YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS": "You have reached the maximum number of organizations", "ORGANIZATION_ALREADY_EXISTS": "Organization already exists", "ORGANIZATION_NOT_FOUND": "Organization not found", "USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION": "User is not a member of the organization", "YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_ORGANIZATION": "You are not allowed to update this organization", "YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_ORGANIZATION": "You are not allowed to delete this organization", "NO_ACTIVE_ORGANIZATION": "No active organization", "USER_IS_ALREADY_A_MEMBER_OF_THIS_ORGANIZATION": "User is already a member of this organization", "MEMBER_NOT_FOUND": "Member not found", "ROLE_NOT_FOUND": "Role not found", "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_TEAM": "You are not allowed to create a new team", "TEAM_ALREADY_EXISTS": "Team already exists", "TEAM_NOT_FOUND": "Team not found", "YOU_CANNOT_LEAVE_THE_ORGANIZATION_AS_THE_ONLY_OWNER": "You cannot leave the organization as the only owner", "YOU_CANNOT_LEAVE_THE_ORGANIZATION_WITHOUT_AN_OWNER": "You cannot leave the organization without an owner", "YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_MEMBER": "You are not allowed to delete this member", "YOU_ARE_NOT_ALLOWED_TO_INVITE_USERS_TO_THIS_ORGANIZATION": "You are not allowed to invite users to this organization", "USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION": "User is already invited to this organization", "INVITATION_NOT_FOUND": "Invitation not found", "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION": "You are not the recipient of the invitation", "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION": "Email verification required before accepting or rejecting invitation", "YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION": "You are not allowed to cancel this invitation", "INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION": "Inviter is no longer a member of the organization", "YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE": "You are not allowed to invite a user with this role", "FAILED_TO_RETRIEVE_INVITATION": "Failed to retrieve invitation", "YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_TEAMS": "You have reached the maximum number of teams", "UNABLE_TO_REMOVE_LAST_TEAM": "Unable to remove last team", "YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER": "You are not allowed to update this member", "ORGANIZATION_MEMBERSHIP_LIMIT_REACHED": "Organization membership limit reached", "YOU_ARE_NOT_ALLOWED_TO_CREATE_TEAMS_IN_THIS_ORGANIZATION": "You are not allowed to create teams in this organization", "YOU_ARE_NOT_ALLOWED_TO_DELETE_TEAMS_IN_THIS_ORGANIZATION": "You are not allowed to delete teams in this organization", "YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_TEAM": "You are not allowed to update this team", "YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_TEAM": "You are not allowed to delete this team", "INVITATION_LIMIT_REACHED": "Invitation limit reached", "TEAM_MEMBER_LIMIT_REACHED": "Team member limit reached", "USER_IS_NOT_A_MEMBER_OF_THE_TEAM": "User is not a member of the team", "YOU_CAN_NOT_ACCESS_THE_MEMBERS_OF_THIS_TEAM": "You are not allowed to list the members of this team", "YOU_DO_NOT_HAVE_AN_ACTIVE_TEAM": "You do not have an active team", "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_TEAM_MEMBER": "You are not allowed to create a new member", "YOU_ARE_NOT_ALLOWED_TO_REMOVE_A_TEAM_MEMBER": "You are not allowed to remove a team member", "YOU_ARE_NOT_ALLOWED_TO_ACCESS_THIS_ORGANIZATION": "You are not allowed to access this organization as an owner", "YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION": "You are not a member of this organization", "MISSING_AC_INSTANCE": "Dynamic Access Control requires a pre-defined ac instance on the server auth plugin. Read server logs for more information", "YOU_MUST_BE_IN_AN_ORGANIZATION_TO_CREATE_A_ROLE": "You must be in an organization to create a role", "YOU_ARE_NOT_ALLOWED_TO_CREATE_A_ROLE": "You are not allowed to create a role", "YOU_ARE_NOT_ALLOWED_TO_UPDATE_A_ROLE": "You are not allowed to update a role", "YOU_ARE_NOT_ALLOWED_TO_DELETE_A_ROLE": "You are not allowed to delete a role", "YOU_ARE_NOT_ALLOWED_TO_READ_A_ROLE": "You are not allowed to read a role", "YOU_ARE_NOT_ALLOWED_TO_LIST_A_ROLE": "You are not allowed to list a role", "YOU_ARE_NOT_ALLOWED_TO_GET_A_ROLE": "You are not allowed to get a role", "TOO_MANY_ROLES": "This organization has too many roles", "INVALID_RESOURCE": "The provided permission includes an invalid resource", "ROLE_NAME_IS_ALREADY_TAKEN": "That role name is already taken", "CANNOT_DELETE_A_PRE_DEFINED_ROLE": "Cannot delete a pre-defined role" }, "options": { "allowUserToCreateOrganization": true } } }, { "name": "two-factor", "config": { "id": "two-factor", "endpoints": {}, "options": { "issuer": "Platform Login", "otpOptions": {} }, "hooks": { "after": [ {} ] }, "schema": { "user": { "fields": { "twoFactorEnabled": { "type": "boolean", "required": false, "defaultValue": false, "input": false } } }, "twoFactor": { "fields": { "secret": { "type": "string", "required": true, "returned": false }, "backupCodes": { "type": "string", "required": true, "returned": false }, "userId": { "type": "string", "required": true, "returned": false, "references": { "model": "user", "field": "id" } } } } }, "rateLimit": [ { "window": 10, "max": 3 } ], "$ERROR_CODES": { "OTP_NOT_ENABLED": "OTP not enabled", "OTP_HAS_EXPIRED": "OTP has expired", "TOTP_NOT_ENABLED": "TOTP not enabled", "TWO_FACTOR_NOT_ENABLED": "Two factor isn't enabled", "BACKUP_CODES_NOT_ENABLED": "Backup codes aren't enabled", "INVALID_BACKUP_CODE": "Invalid backup code", "INVALID_CODE": "Invalid code", "TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE": "Too many attempts. Please request a new code.", "INVALID_TWO_FACTOR_COOKIE": "Invalid two factor cookie" } } }, { "name": "multi-session", "config": { "id": "multi-session", "endpoints": {}, "hooks": { "after": [ {}, {} ] }, "$ERROR_CODES": { "INVALID_SESSION_TOKEN": "[REDACTED]" } } }, { "name": "last-login-method", "config": { "id": "last-login-method", "hooks": { "after": [ {} ] } } }, { "name": "api-key", "config": { "id": "api-key", "$ERROR_CODES": { "INVALID_METADATA_TYPE": "metadata must be an object or undefined", "REFILL_AMOUNT_AND_INTERVAL_REQUIRED": "refillAmount is required when refillInterval is provided", "REFILL_INTERVAL_AND_AMOUNT_REQUIRED": "refillInterval is required when refillAmount is provided", "USER_BANNED": "User is banned", "UNAUTHORIZED_SESSION": "Unauthorized or invalid session", "KEY_NOT_FOUND": "API Key not found", "KEY_DISABLED": "API Key is disabled", "KEY_EXPIRED": "API Key has expired", "USAGE_EXCEEDED": "API Key has reached its usage limit", "KEY_NOT_RECOVERABLE": "API Key is not recoverable", "EXPIRES_IN_IS_TOO_SMALL": "The expiresIn is smaller than the predefined minimum value.", "EXPIRES_IN_IS_TOO_LARGE": "The expiresIn is larger than the predefined maximum value.", "INVALID_REMAINING": "The remaining count is either too large or too small.", "INVALID_PREFIX_LENGTH": "The prefix length is either too large or too small.", "INVALID_NAME_LENGTH": "The name length is either too large or too small.", "METADATA_DISABLED": "Metadata is disabled.", "RATE_LIMIT_EXCEEDED": "Rate limit exceeded.", "NO_VALUES_TO_UPDATE": "No values to update.", "KEY_DISABLED_EXPIRATION": "Custom key expiration values are disabled.", "INVALID_API_KEY": "Invalid API key.", "INVALID_USER_ID_FROM_API_KEY": "The user id from the API key is invalid.", "INVALID_API_KEY_GETTER_RETURN_TYPE": "API Key getter returned an invalid key type. Expected string.", "SERVER_ONLY_PROPERTY": "The property you're trying to set can only be set from the server auth instance only.", "FAILED_TO_UPDATE_API_KEY": "Failed to update API key", "NAME_REQUIRED": "API Key name is required." }, "hooks": { "before": [ {} ] }, "endpoints": {}, "schema": { "apikey": { "fields": { "name": { "type": "string", "required": false, "input": false }, "start": { "type": "string", "required": false, "input": false }, "prefix": { "type": "string", "required": false, "input": false }, "key": { "type": "string", "required": true, "input": false }, "userId": { "type": "string", "references": { "model": "user", "field": "id", "onDelete": "cascade" }, "required": true, "input": false }, "refillInterval": { "type": "number", "required": false, "input": false }, "refillAmount": { "type": "number", "required": false, "input": false }, "lastRefillAt": { "type": "date", "required": false, "input": false }, "enabled": { "type": "boolean", "required": false, "input": false, "defaultValue": true }, "rateLimitEnabled": { "type": "boolean", "required": false, "input": false, "defaultValue": true }, "rateLimitTimeWindow": { "type": "number", "required": false, "input": false, "defaultValue": 86400000 }, "rateLimitMax": { "type": "number", "required": false, "input": false, "defaultValue": 10 }, "requestCount": { "type": "number", "required": false, "input": false, "defaultValue": 0 }, "remaining": { "type": "number", "required": false, "input": false }, "lastRequest": { "type": "date", "required": false, "input": false }, "expiresAt": { "type": "date", "required": false, "input": false }, "createdAt": { "type": "date", "required": true, "input": false }, "updatedAt": { "type": "date", "required": true, "input": false }, "permissions": { "type": "string", "required": false, "input": false }, "metadata": { "type": "string", "required": false, "input": true, "transform": {} } } } } } }, { "name": "oidc", "config": { "id": "oidc", "hooks": { "after": [ {} ] }, "endpoints": {}, "schema": { "oauthApplication": { "modelName": "oauthApplication", "fields": { "name": { "type": "string" }, "icon": { "type": "string", "required": false }, "metadata": { "type": "string", "required": false }, "clientId": { "type": "string", "unique": true }, "clientSecret": { "type": "string", "required": false }, "redirectURLs": { "type": "string" }, "type": { "type": "string" }, "disabled": { "type": "boolean", "required": false, "defaultValue": false }, "userId": { "type": "string", "required": false, "references": { "model": "user", "field": "id", "onDelete": "cascade" } }, "createdAt": { "type": "date" }, "updatedAt": { "type": "date" } } }, "oauthAccessToken": { "modelName": "oauthAccessToken", "fields": { "accessToken": { "type": "string", "unique": true }, "refreshToken": { "type": "string", "unique": true }, "accessTokenExpiresAt": { "type": "date" }, "refreshTokenExpiresAt": { "type": "date" }, "clientId": { "type": "string", "references": { "model": "oauthApplication", "field": "clientId", "onDelete": "cascade" } }, "userId": { "type": "string", "required": false, "references": { "model": "user", "field": "id", "onDelete": "cascade" } }, "scopes": { "type": "string" }, "createdAt": { "type": "date" }, "updatedAt": { "type": "date" } } }, "oauthConsent": { "modelName": "oauthConsent", "fields": { "clientId": { "type": "string", "references": { "model": "oauthApplication", "field": "clientId", "onDelete": "cascade" } }, "userId": { "type": "string", "references": { "model": "user", "field": "id", "onDelete": "cascade" } }, "scopes": { "type": "string" }, "createdAt": { "type": "date" }, "updatedAt": { "type": "date" }, "consentGiven": { "type": "boolean" } } } } } }, { "name": "open-api", "config": { "id": "open-api", "endpoints": {} } } ], "socialProviders": { "github": { "clientId": "", "clientSecret": "", "enabled": false }, "google": { "clientId": "[REDACTED]", "clientSecret": "[REDACTED]", "enabled": true } }, "session": { "expiresIn": 604800, "updateAge": 86400, "cookieCache": { "enabled": true, "maxAge": 300 } }, "user": { "additionalFields": { "emailVerified": { "type": "boolean", "required": false, "defaultValue": false } } }, "advanced": { "database": {} }, "trustedOrigins": [ "http://localhost:3000", "http://localhost:5173", "http://localhost:4321" ], "baseURL": "http://localhost:3000", "secret": "[REDACTED]" } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-17 18:44:08 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Oct 27, 2025):

This error is a known limitation: when you call the send-verification-email endpoint as an admin, Better Auth checks the emailVerified status of the session user (the admin), not the target user whose email you want to verify. This means the request is blocked even if the target user's emailVerified field is false in the database. The intended behavior is only supported for self-service (the user requesting their own verification email) and not for admins resending verification emails to other users see discussion.

A workaround is to make the request without being logged in as an admin, or impersonate the target user so the session matches the user whose email needs verification. If you need to automate admin-triggered verification emails, you may need to patch the endpoint logic to check the target user's emailVerified status directly, or use a custom server-side flow.

If you want more details on how to implement a workaround or patch, let me know!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3452495534 --> @dosubot[bot] commented on GitHub (Oct 27, 2025): <!-- Answer --> This error is a known limitation: when you call the send-verification-email endpoint as an admin, Better Auth checks the emailVerified status of the session user (the admin), not the target user whose email you want to verify. This means the request is blocked even if the target user's emailVerified field is false in the database. The intended behavior is only supported for self-service (the user requesting their own verification email) and not for admins resending verification emails to other users [see discussion](https://github.com/better-auth/better-auth/issues/4781). A workaround is to make the request without being logged in as an admin, or impersonate the target user so the session matches the user whose email needs verification. If you need to automate admin-triggered verification emails, you may need to patch the endpoint logic to check the target user's emailVerified status directly, or use a custom server-side flow. If you want more details on how to implement a workaround or patch, let me know! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/5b3d7cc4-7a25-494d-ac28-0d51627a244a?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/5621)
Author
Owner

@bnssoftware commented on GitHub (Oct 27, 2025):

so if it's only for the currently logged in user, why do I need to specify the email address?

<!-- gh-comment-id:3453024565 --> @bnssoftware commented on GitHub (Oct 27, 2025): so if it's only for the currently logged in user, why do I need to specify the email address?
Author
Owner

@dosubot[bot] commented on GitHub (Oct 27, 2025):

The email parameter is required for the send-verification-email endpoint because the API supports both unauthenticated and authenticated modes. If you're not logged in, the email is used to look up the user and send the verification email. If you are logged in, the endpoint checks that the email you provide matches your own email as an integrity check—this prevents users from triggering verification emails for other accounts and helps avoid privacy leaks or abuse. So, even though it only works for your own account when logged in, the parameter is still required for consistency and security across both use cases.
See implementation details

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3453032973 --> @dosubot[bot] commented on GitHub (Oct 27, 2025): <!-- Answer --> The email parameter is required for the send-verification-email endpoint because the API supports both unauthenticated and authenticated modes. If you're not logged in, the email is used to look up the user and send the verification email. If you are logged in, the endpoint checks that the email you provide matches your own email as an integrity check—this prevents users from triggering verification emails for other accounts and helps avoid privacy leaks or abuse. So, even though it only works for your own account when logged in, the parameter is still required for consistency and security across both use cases. [See implementation details](https://github.com/better-auth/better-auth/blob/5b491010505ef5041b6ec9c83149029deabd894a/packages/better-auth/src/api/routes/email-verification.ts) <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d5180e2a-3774-417e-8d4b-e2b9c59674a4?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/5621)
Author
Owner

@ping-maxwell commented on GitHub (Jan 9, 2026):

Hello looking at our source code it seems that it's intentional for that endpoint not to be called by the user other than the one who intends to verify.

The "email already verified" error stems from your admin account being email verified, not the user who you're trying to send the invitation to. If your email wasn't verified you would had seen the correct error message stating that you can't perform that action on behalf of another user.

I've opened a PR to make the correct error appear first to reduce confusion in the future.

<!-- gh-comment-id:3727149244 --> @ping-maxwell commented on GitHub (Jan 9, 2026): Hello looking at our source code it seems that it's intentional for that endpoint not to be called by the user other than the one who intends to verify. The "email already verified" error stems from your admin account being email verified, not the user who you're trying to send the invitation to. If your email wasn't verified you would had seen the correct error message stating that you can't perform that action on behalf of another user. I've opened a [PR](https://github.com/better-auth/better-auth/pull/7215) to make the correct error appear first to reduce confusion in the future.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#27628