TryGhost/Ghost · error · ValidationError

The server did not receive a valid email

Error message

The server did not receive a valid email

What it means

Thrown by the `sendTestEmail` validator when `frame.data.email` is not a string or fails `validator.isEmail`. Before sending a test email, Ghost validates the recipient address format; an invalid address yields a 422 ValidationError with `invalidEmailReceived`. After this check, `validatePreviewData` also runs.

Source

Thrown at ghost/core/core/server/api/endpoints/utils/validators/input/automated_emails.js:131

        validateOptionalStringField(senderName, 'Sender name must be a string');
        validateOptionalStringField(senderEmail, 'Sender email must be a string');
        validateOptionalStringField(senderReplyTo, 'Reply-to email must be a string');
    },
    verifySenderUpdate(apiConfig, frame) {
        if (typeof frame.data.token !== 'string' || !frame.data.token.trim()) {
            throw new ValidationError({
                message: tpl(messages.tokenRequired)
            });
        }
    },
    preview(apiConfig, frame) {
        validatePreviewData(frame);
    },
    sendTestEmail(apiConfig, frame) {
        const email = frame.data.email;

        if (typeof email !== 'string' || !validator.isEmail(email)) {
            throw new ValidationError({
                message: tpl(messages.invalidEmailReceived)
            });
        }

        validatePreviewData(frame);
    }
};

View on GitHub (pinned to 47d8b0e2ad)

Solutions

  1. Validate the email address format client-side (regex or `validator.isEmail`) before sending.
  2. Ensure the `email` field is present and a non-empty valid string in the request body.
  3. Trim whitespace from the input before validation.

Example fix

// before
await api.email.sendTestEmail({data: {email: 'not-an-email', subject, lexical}});

// after
await api.email.sendTestEmail({data: {email: 'user@example.com', subject, lexical}});
Defensive patterns

Strategy: validation

Validate before calling

import validator from '@tryghost/validator';
function isValidEmail(v: unknown): boolean {
    return typeof v === 'string' && validator.isEmail(v);
}
if (!isValidEmail(payload.email)) {
    throw new Error('email must be a valid email address');
}

Type guard

function isValidEmail(v: unknown): v is string {
    return typeof v === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
}

Prevention

When it happens

Trigger: A send-test-email request omits `email`, sends a non-string, or sends a syntactically invalid email address (missing `@`, bad domain, stray characters).

Common situations: Frontend submits before validating the email input; typo in the address; payload uses wrong key; empty string; user-provided address not sanitized.

Related errors


AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13). Data as JSON: /api/errors/1de0bfcfca9426a3. Report an issue: GitHub.