It's a bug of Magento as wrote in the comment of your question.
I resolved the problem in this way (but I changed order comments email vars, but use the same changes for invoice core classes):
1) I created a preference class for the core class because it is a bad way to write code in the core file.
- added in di.xml code
<preference for="Magento\Sales\Model\Order\Email\Sender\OrderCommentSender" type="Namespace\ExtensionName\Model\Order\Email\Sender\OrderCommentSender" />
2) Fixed source code in my class. The main idea: we added prepare template and we need to extend source \Magento\Sales\Model\Order\Email\Sender\OrderCommentSender to prevent another core error.
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Sfdev\SecretDelivery\Model\Order\Email\Sender;
use Magento\Framework\Oauth\Exception;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity;
use Magento\Sales\Model\Order\Email\Container\Template;
use Magento\Sales\Model\Order\Email\NotifySender;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\Event\ManagerInterface;
/**
* Class OrderCommentSender
*/
class OrderCommentSender extends **\Magento\Sales\Model\Order\Email\Sender\OrderCommentSender**
{
/**
* @var Renderer
*/
protected $addressRenderer;
/**
* Application Event Dispatcher
*
* @var ManagerInterface
*/
protected $eventManager;
**public $comment = '';**
/**
* @param Template $templateContainer
* @param OrderCommentIdentity $identityContainer
* @param Order\Email\SenderBuilderFactory $senderBuilderFactory
* @param \Psr\Log\LoggerInterface $logger
* @param Renderer $addressRenderer
* @param ManagerInterface $eventManager
*/
public function __construct(
Template $templateContainer,
OrderCommentIdentity $identityContainer,
\Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
\Psr\Log\LoggerInterface $logger,
Renderer $addressRenderer,
ManagerInterface $eventManager
) {
parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger, $addressRenderer, $eventManager);
$this->addressRenderer = $addressRenderer;
$this->eventManager = $eventManager;
}
/**
* Send email to customer
*
* @param Order $order
* @param bool $notify
* @param string $comment
* @return bool
*/
public function send(Order $order, $notify = true, $comment = '')
{
**$this->comment = $comment;**
return $this->checkAndSend($order, $notify);
}
/**
* Prepare email template with variables
*
* @param Order $order
* @return void
*/
**protected function prepareTemplate(Order $order)**
{
$transport = [
'order' => $order,
'comment' => $this->comment,
'billing' => $order->getBillingAddress(),
'store' => $order->getStore(),
'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
];
$transport = new \Magento\Framework\DataObject($transport);
$this->eventManager->dispatch(
'email_order_comment_set_template_vars_before',
['sender' => $this, 'transport' => $transport]
);
try {
$this->templateContainer->setTemplateVars($transport->getData());
parent::prepareTemplate($order);
} catch (\Exception $e) {
$this->logger->error('ERROR EMAIL VARS');
$this->logger->error($e->getMessage());
}
}
}
3) The result is - we can use core dispatch 'email_order_comment_set_template_vars_before' - it is working correctly