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
- Use only 'text' and 'html' keys in the content array
- Replace legacy 'both' with two entries: ['text' => ..., 'html' => ...]
- 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
- Use setBodyText()/setBodyHtml() wrappers instead of raw setBody
- Lowercase all keys before passing
- Replace legacy 'both'/'css' keys during upgrades
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
- Format not available.
- At least one case needed for `enumExcept()` validation.
- At least one case needed for `enumOnly()` validation.
- No file or data specified.
- No filename specified.
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)