Problem/Motivation

symfony_mailer uses the Symfony\Component\Mime\Address class to create an Address object. This component can't have NULL as an email value, only Strings are allowed. This Symfony Address is constructed from the Symfony_mailer Address class in Address->getSymfony() method.

A NULL value will result in the following error: TypeError: Symfony\Component\Mime\Address::__construct(): Argument #1 ($address) must be of type string, null given, called in /var/www/site/htdocs/modules/contrib/symfony_mailer/src/Address.php

I found out about this bug running drush cim using the role_test_accounts module which creates accounts with no email set (thus null). The core User module sends an email postSave in its User entity object where it notifies the user. Also when deleting (and notifying) a user with no email set will cause this error.

Full error log for role_test_accounts using drush cim:

#1 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Address.php(142): Drupal\symfony_mailer\Address::create(Object(Drupal\user\Entity\User))
#2 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/BaseEmailTrait.php(62): Drupal\symfony_mailer\Address::convert(Array)
#3 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/BaseEmailTrait.php(98): Drupal\symfony_mailer\Email->setAddress('To', Object(Drupal\user\Entity\User))
#4 /var/www/html/htdocs/modules/contrib/symfony_mailer/modules/symfony_mailer_bc/src/Plugin/EmailBuilder/UserEmailBuilder.php(69): Drupal\symfony_mailer\Email->setTo(Object(Drupal\user\Entity\User))
#5 [internal function]: Drupal\symfony_mailer_bc\Plugin\EmailBuilder\UserEmailBuilder->build(Object(Drupal\symfony_mailer\Email))
#6 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Email.php(460): call_user_func(Array, Object(Drupal\symfony_mailer\Email))
#7 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Mailer.php(164): Drupal\symfony_mailer\Email->process()
#8 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Mailer.php(139): Drupal\symfony_mailer\Mailer->doSend(Object(Drupal\symfony_mailer\Email))
#9 /var/www/html/htdocs/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\symfony_mailer\Mailer->Drupal\symfony_mailer\{closure}()
#10 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Mailer.php(148): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#11 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Email.php(278): Drupal\symfony_mailer\Mailer->send(Object(Drupal\symfony_mailer\Email))
#12 /var/www/html/htdocs/modules/contrib/symfony_mailer/modules/symfony_mailer_bc/src/MailManagerReplacement.php(97): Drupal\symfony_mailer\Email->send()
#13 /var/www/html/htdocs/core/modules/user/user.module(1071): Drupal\symfony_mailer_bc\MailManagerReplacement->mail('user', 'status_activate...', NULL, 'en', Array, 'no-reply@examp...')
#14 /var/www/html/htdocs/core/modules/user/src/Entity/User.php(139): _user_mail_notify('status_activate...', Object(Drupal\user\Entity\User))
#15 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/EntityStorageBase.php(597): Drupal\user\Entity\User->postSave(Object(Drupal\user\UserStorage), true)
#16 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(784): Drupal\Core\Entity\EntityStorageBase->doPostSave(Object(Drupal\user\Entity\User), true)
#17 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/EntityStorageBase.php(523): Drupal\Core\Entity\ContentEntityStorageBase->doPostSave(Object(Drupal\user\Entity\User), true)
#18 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(802): Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\user\Entity\User))
#19 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/EntityBase.php(339): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object(Drupal\user\Entity\User))
#20 /var/www/html/htdocs/modules/contrib/role_test_accounts/src/RoleTestAccountsManager.php(72): Drupal\Core\Entity\EntityBase->save()
#21 /var/www/html/htdocs/modules/contrib/role_test_accounts/src/RoleTestAccountsManager.php(114): Drupal\role_test_accounts\RoleTestAccountsManager->createTestAccount('test_admin')
#22 /var/www/html/htdocs/modules/contrib/role_test_accounts/src/EventSubscriber/RoleTestAccountsSettingsSubscriber.php(44): Drupal\role_test_accounts\RoleTestAccountsManager->generateRoleTestAccounts(Object(Drupal\Core\Config\Config))
#23 [internal function]: Drupal\role_test_accounts\EventSubscriber\RoleTestAccountsSettingsSubscriber->onSave(Object(Drupal\Core\Config\ConfigCrudEvent), 'config.save', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#24 /var/www/html/htdocs/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Drupal\Core\Config\ConfigCrudEvent), 'config.save', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#25 /var/www/html/htdocs/core/lib/Drupal/Core/Config/Config.php(229): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Drupal\Core\Config\ConfigCrudEvent), 'config.save')
#26 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(943): Drupal\Core\Config\Config->save()
#27 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(787): Drupal\Core\Config\ConfigImporter->importConfig('', 'update', 'role_test_accou...')
#28 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(605): Drupal\Core\Config\ConfigImporter->processConfiguration('', 'update', 'role_test_accou...')
#29 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(509): Drupal\Core\Config\ConfigImporter->processConfigurations(Array)
#30 /var/www/html/vendor/drush/drush/src/Drupal/Commands/config/ConfigImportCommands.php(336): Drupal\Core\Config\ConfigImporter->doSyncStep('processConfigur...', Array)
#31 /var/www/html/vendor/drush/drush/includes/drush.inc(206): Drush\Drupal\Commands\config\ConfigImportCommands->doImport(Object(Drupal\Core\Config\StorageComparer))
#32 /var/www/html/vendor/drush/drush/includes/drush.inc(197): drush_call_user_func_array(Array, Array)
#33 /var/www/html/vendor/drush/drush/src/Drupal/Commands/config/ConfigImportCommands.php(307): drush_op(Array, Object(Drupal\Core\Config\StorageComparer))
#34 [internal function]: Drush\Drupal\Commands\config\ConfigImportCommands->import(NULL, Array)
#35 /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call_user_func_array(Array, Array)
#36 /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
#37 /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(176): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#38 /var/www/html/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(311): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#39 /var/www/html/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#40 /var/www/html/vendor/symfony/console/Application.php(1027): Symfony\Component\Console\Command\Command->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#41 /var/www/html/vendor/symfony/console/Application.php(273): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#42 /var/www/html/vendor/symfony/console/Application.php(149): Symfony\Component\Console\Application->doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#43 /var/www/html/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#44 /var/www/html/vendor/drush/drush/src/Runtime/Runtime.php(48): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#45 /var/www/html/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array)
#46 /var/www/html/vendor/drush/drush/drush(4): require('/var/www/html/v...')
#47 /var/www/html/vendor/bin/drush(120): include('/var/www/html/v...')
#48 {main}.

Steps to reproduce

*DELETE USER AND NOTIFY*
- Enable symfony_mailer and its BC sub-module.
- Create a user with no email set. Delete and notify the user.
- The mail should fail and cause the error above because no email is set.

*ROLE_TEST_ACCOUNTS*
- Enable symfony_mailer and its BC sub-module.
- Enable role_test_accounts
- Configure role_test_accounts to create specific users with no email set
- Alter and/or delete some generated accounts
- Run drush cim

role_test_accounts should call a postSave on the user entity which will cause these errors.

Proposed resolution

Convert NULL values to empty strings in the symfony_mailer Address constructor. See patch

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

danekin created an issue. See original summary.

daneduijnkerke’s picture

Patch added.

daneduijnkerke’s picture

daneduijnkerke’s picture

Status: Active » Needs review
ronald van belzen’s picture

Maybe the following would be better, instead of the if-statement:

  $this->email = $email ?? '';
adamps’s picture

Title: A Symfony Address can't be NULL » Error notifying users without an email address
Status: Needs review » Needs work
Issue tags: -symfony, -email address, -null value

Thanks for the report and patch.

The issue is about notifying a user with no email. We should check what Core does and copy that. The proposed solution is that when silently ignore the problem. Another possibility would be to raise an error report.

I propose we leave the code in Address - it's correct that the email field is mandatory for this class. I would fix instead in UserEmailBuilder::build(). If the user has no address, then throw a SkipMailException.

nojj’s picture

I am having a very similar error, when creating a new user account from backend without email address.

eher massage is:

TypeError: Argument 1 passed to Drupal\symfony_mailer\Address::__construct() must be of the type string, null given, called in /var/www/html/web/modules/contrib/symfony_mailer/src/Address.php on line 83 in Drupal\symfony_mailer\Address->__construct() (Zeile 58 in /var/www/html/web/modules/contrib/symfony_mailer/src/Address.php)

is this fixed in a later release ?
i testet latest beta 1.1.0 bata3 and the issue still exits.

stijnstroobants’s picture

StatusFileSize
new530 bytes

As mentioned above this is not the best solution, but created a patch for 1.6.x

v.hilkov’s picture

StatusFileSize
new737 bytes

Last patch didn't worked, I made $email in __construct() nullable

adamps’s picture

The code in _user_mail_notify() generates a log and skips sending, so we should do that here.

adamps’s picture

Version: 1.0.0-alpha11 » 2.x-dev

adamps’s picture

Status: Needs work » Needs review

This was fixed in Core by #3518058: _user_mail_notify() doesn't handle accounts without an email address. It could still be hit by calling UserMailer directly. Seeing as I have just written the code, I might as well commit it to cover this case.

  • adamps committed 75cb492c on 2.x
    fix: #3305696 Error notifying users without an email address
    
    By:...
adamps’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.