Running cron to generate an expiration warning to a user, I got the following message:
Warning: htmlspecialchars() expects parameter 1 to be string, object given in Drupal\Component\Utility\Html::escape() (line 424 of core/lib/Drupal/Component/Utility/Html.php).
Drupal\Component\Utility\Html::escape(Object) (Line: 260)
Drupal\Component\Render\FormattableMarkup::placeholderEscape(Object) (Line: 206)
Drupal\Component\Render\FormattableMarkup::placeholderFormat('Because you have not logged in recently, your account at @site_name will be blocked in the near future. If you still use this site, please log in @login_url to avoid having your account blocked.', Array) (Line: 195)
Drupal\Core\StringTranslation\TranslatableMarkup->render() (Line: 15)
Drupal\Core\StringTranslation\TranslatableMarkup->__toString() (Line: 288)
Drupal\Core\Mail\MailManager->doMail('user_expire', 'expiration_warning', 'test@example.com', 'en', Array, NULL, 1) (Line: 180)
Drupal\Core\Mail\MailManager->Drupal\Core\Mail\{closure}() (Line: 578)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 181)
Drupal\Core\Mail\MailManager->mail('user_expire', 'expiration_warning', 'test@example.com', 'en', Array) (Line: 344)
user_expire_expire_by_role_warning() (Line: 176)
user_expire_cron()
call_user_func_array('user_expire_cron', Array) (Line: 392)
Drupal\Core\Extension\ModuleHandler->invoke('user_expire', 'cron') (Line: 250)
Drupal\Core\Cron->invokeCronHandlers() (Line: 136)
Drupal\Core\Cron->run() (Line: 75)
Drupal\Core\ProxyClass\Cron->run() (Line: 272)
Drupal\admin_toolbar_tools\Controller\ToolbarController->runCron()
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 578)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 49)
Asm89\Stack\Cors->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 717)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
The problem was caused by passing a Url object into the t() function, rather than a string. The attached patch got rid of the warning.