coollabsio/coolify · warning · Exception
Recipient is not part of the team
Error message
Recipient is not part of the team
What it means
EmailChannel validates every resolved recipient against the team's member emails ($members->contains('email', $recipient)). A recipient not on that list — custom email of an outsider, a stale address, a case-mismatched duplicate — first triggers an internal notification (with masked SMTP/Resend secrets) and then throws, aborting the whole email send.
Source
Thrown at app/Notifications/Channels/EmailChannel.php:64
// Skip team membership validation for test notifications
$isTestNotification = data_get($notification, 'isTestNotification', false);
if (! $isTestNotification) {
foreach ($recipients as $recipient) {
// Check if the recipient is part of the team
if (! $members->contains('email', $recipient)) {
$emailSettings = $notifiable->emailNotificationSettings;
data_set($emailSettings, 'smtp_password', '********');
data_set($emailSettings, 'resend_api_key', '********');
send_internal_notification(sprintf(
"Recipient is not part of the team: %s\nTeam: %s\nNotification: %s\nNotifiable: %s\nEmail Settings:\n%s",
$recipient,
$team,
get_class($notification),
get_class($notifiable),
json_encode($emailSettings, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
));
throw new Exception('Recipient is not part of the team');
}
}
}
$mailMessage = $notification->toMail($notifiable);
if ($isResendEnabled) {
$resend = Resend::client($settings->resend_api_key);
$from = "{$settings->smtp_from_name} <{$settings->smtp_from_address}>";
$resend->emails->send([
'from' => $from,
'to' => $recipients,
'subject' => $mailMessage->subject,
'html' => (string) $mailMessage->render(),
]);
} elseif ($isSmtpEnabled) {
$encryption = match (strtolower($settings->smtp_encryption)) {
'starttls' => null,View on GitHub (pinned to 70b9acc424)
Solutions
- Use email addresses that exactly match current team members (check Members list).
- Remove or update stale custom recipients after members change their email.
- Match the address casing used on the member record.
- To notify externals, invite them as team members first — Coolify enforces team membership by design.
Example fix
// before: custom recipient outside the team
$notification->setEmailRecipients('client@example.com');
// after: only team member addresses
$notification->setEmailRecipients($team->members()->pluck('email')->implode(',')); Defensive patterns
Strategy: validation
Validate before calling
// Filter recipients to verified team member emails before sending
$memberEmails = $team->members()->pluck('email')->map(fn ($e) => strtolower(trim($e)))->all();
$recipients = array_values(array_filter($recipients, fn ($r) => in_array(strtolower(trim($r)), $memberEmails, true)));
if ($recipients === []) { /* skip or warn instead of mid-send failure */ } Try / catch
catch (Exception $e) { if ($e->getMessage() === 'Recipient is not part of the team') { flag the notification's recipient list as stale in settings UI rather than crashing the send loop. } else { throw $e; } } Prevention
- Source custom recipients only from the member picker, never free text.
- When members change their email, update notification recipients automatically.
- Normalize casing/whitespace before comparing or storing emails.
When it happens
Trigger: Custom recipient typed with a typo or belonging to a non-member; team member changed their email but notification settings/custom recipients still hold the old one; mixed-case address not exactly matching the stored member email (comparison is exact).
Common situations: Sending deployment notifications to a client's address not on the team; member email rotation; uppercase variants of the same Gmail address.
Related errors
- No email recipients found
- No email settings found.
- No email settings found.
- Too many messages sent!
- Pre-deployment command: Could not find a valid container. Is
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/13f03b0b9a68ee36.
Report an issue: GitHub.