appwrite/appwrite · error · AppwriteException

Missing required parameter: "email"

Error message

Missing required parameter: "email"

What it means

Thrown by Account.create when userId passed but email is undefined. Email is checked second. Synchronous pre-network guard.

Source

Thrown at public/sdk-project/services/account.ts:54

         * the [/account/verfication](/docs/client/account#accountCreateVerification)
         * route to start verifying the user email address. To allow the new user to
         * login to their new account, you need to create a new [account
         * session](/docs/client/account#accountCreateSession).
         *
         * @param {string} userId
         * @param {string} email
         * @param {string} password
         * @param {string} name
         * @throws {AppwriteException}
         * @returns {Promise}
         */
        async create<Preferences extends Models.Preferences>(userId: string, email: string, password: string, name?: string): Promise<Models.Account<Preferences>> {
            if (typeof userId === 'undefined') {
                throw new AppwriteException('Missing required parameter: "userId"');
            }

            if (typeof email === 'undefined') {
                throw new AppwriteException('Missing required parameter: "email"');
            }

            if (typeof password === 'undefined') {
                throw new AppwriteException('Missing required parameter: "password"');
            }

            let path = '/account';
            let payload: Payload = {};

            if (typeof userId !== 'undefined') {
                payload['userId'] = userId;
            }

            if (typeof email !== 'undefined') {
                payload['email'] = email;
            }

            if (typeof password !== 'undefined') {

View on GitHub (pinned to cd368e707d)

Solutions

  1. Bind the email input to state and validate before submit: if (!email) setFieldError('email', 'required');
  2. Use a name='email' form field and read `formData.get('email')`.
  3. Add HTML5 required + type=email on the input as a first-line guard.

Example fix

// before
await account.create(ID.unique(), form.emailAddress, password); // wrong field name

// after
const email = form.email?.trim();
if (!email) { throw new Error('Email is required'); }
await account.create(ID.unique(), email, password);
Defensive patterns

Strategy: validation

Validate before calling

const email = form.email?.trim();
if (!email || !/^[^@]+@[^@]+\.[^@]+$/.test(email)) {
  throw new Error('Valid email is required');
}
await account.create(userId, email, password);

Type guard

const isEmail = (v: unknown): v is string =>
  typeof v === 'string' && /^[^@]+@[^@]+\.[^@]+$/.test(v);

Try / catch

try {
  await account.create(userId, email, password);
} catch (e) {
  if (e instanceof AppwriteException && /Missing required parameter/.test(e.message)) {
    setFormError(e.message);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Signup form submitted with an empty/missing email field whose value reads as undefined; reading `form.email` off a FormData without the key; passing an object instead of the string.

Common situations: Input named differently (`emailAddress` vs `email`); controlled input whose state was not bound; paste-and-clear leaving the field undefined rather than ''.

Related errors


AI-assisted analysis of appwrite/appwrite@cd368e707d (2026-08-12). Data as JSON: /api/errors/18370689c9cd3252. Report an issue: GitHub.