cakephp/cakephp · error · InvalidArgumentException

Invalid message type

Error message

Invalid message type: `%s`. Valid types are: `text`, `html`.

What it means

Message::setBody(array $content) iterates over keys of the content array and requires each key to be a valid format in ['text','html']. An unknown key throws InvalidArgumentException('Invalid message type: `%s`. Valid types are: `text`, `html`.').

Solutions

  1. Use only 'text' and 'html' keys in the content array
  2. Replace legacy 'both' with two entries: ['text' => ..., 'html' => ...]
  3. Fix key casing — keys are lowercase and strict (in_array with true)

Example fix

// before
$message->setBody(['both' => $content]);
// after
$message->setBody(['text' => $content, 'html' => $htmlContent]);
Defensive patterns

Strategy: validation

Validate before calling

$valid = ['text', 'html'];
foreach (array_keys($content) as $type) {
    if (!in_array($type, $valid, true)) {
        unset($content[$type]); // or throw
    }
}
$message->setBody($content);

Type guard

function isValidBodyKey(mixed $type): bool {
    return is_string($type) && in_array($type, ['text', 'html'], true);
}

Try / catch

try {
    $message->setBody($content);
} catch (\InvalidArgumentException $e) {
    $message->setBody(array_intersect_key($content, ['text' => 1, 'html' => 1]));
}

Prevention

When it happens

Trigger: setBody(['both' => $text]), setBody(['Html' => $html]) (capitalized key), or any key other than 'text'/'html'. Reached via setBodyText/setBodyHtml wrappers only for valid keys, so direct setBody calls are the source.

Common situations: Porting CakePHP 3 code that used ['both' => ...]; building the array dynamically from config; using 'plain' or 'raw' as key names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of cakephp/cakephp@1128eba9b0 (2026-09-12). Data as JSON: /api/errors/66492d28b67191c5. Report an issue: GitHub.

Appendix: source

Thrown at src/Mailer/Message.php:1540

        if (isset($config['headers'])) {
            $this->setHeaders($config['headers']);
        }

        return $this;
    }

    /**
     * Set message body.
     *
     * @param array<string, string> $content Content array with keys "text" and/or "html" with
     *   content string of respective type.
     * @return $this
     */
    public function setBody(array $content)
    {
        foreach ($content as $type => $text) {
            if (!in_array($type, $this->emailFormatAvailable, true)) {
                throw new InvalidArgumentException(sprintf(
                    'Invalid message type: `%s`. Valid types are: `text`, `html`.',
                    $type,
                ));
            }

            $text = str_replace(["\r\n", "\r"], "\n", $text);
            $text = $this->encodeString($text, $this->getCharset());
            $text = $this->wrap($text);
            $text = implode("\n", $text);
            $text = rtrim($text, "\n");

            $property = "{$type}Message";
            $this->$property = $text;
        }

        $this->boundary = null;
        $this->message = [];

View on GitHub (pinned to 1128eba9b0)