Magento2 - Command-Line - Sending Email Using Block Templates - Error: Missing required argument $debugHintsPath

I finally found the solution to this problem in the Magento Community Forums, which was provided by @dunagan5887. I decided to share it here on magento.stackexchange.com as many may benefit from a well refered solution to this exception.

There is a link to the original Community Forum post: Email template with block

It seems that this solution, as quoted by @dunagan5887; dictates that the di.xml directive set in vendor/magento/module-developer/etc/adminhtml/di.xml is loaded.

The Solution Consists of this Simple Line of Code:

$this->_objectManager->configure($this->_configLoader->load('adminhtml'));


Please find a working version command line class below:

app/code/NameSpace/Module/Console/Command.php

<?php
namespace NameSpace\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CustomCommandClass extends Command
{
    public function __construct(
        \Magento\Framework\App\State $state,
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Framework\ObjectManager\ConfigLoaderInterface $configLoader
    ) {
        $state->setAreaCode('frontend'); //SET CURRENT AREA
        $objectManager->configure($configLoader->load('frontend')); //SOLUTION
        parent::__construct();
    }

    ...

}

Simply change the area from frontend to admin or global as required by your application.


[UPDATE]

Area adminhtml causing static content deploy errors

It seems that for some reasons setting the area to adminhtml is causing some errors while deploying static contents.

We were seeing errors like the following:

Fatal error: Uncaught Exception: Warning: Error while sending QUERY packet. PID=22912 in ../magento/vendor/magento/zendframework1/library/Zend/Db/Statement/Pdo.php on line 228 in ../magento/vendor/magento/framework/App/ErrorHandler.php:61

I initially thought that this error would be caused by a low max_allowed_packet setting for MYSQL but as the limit was already high enough and raising it wasn't resolving the issue, I decided to dig further. After going through an elimination process I finally found out that this was the main difference between two modules using similar command functions, from which one of the modules was causing this issue as soon as enabled.

Although I haven't digged to find the source of this issue or conflict, I thought it would be a good idea to share my findings here as others may find it useful.


[UPDATE - 2]

The right method:

After upgrading Magento to 2.2.X we realized that this is the right method for setting the area:

app/code/NameSpace/Module/Console/Command.php

<?php
namespace NameSpace\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CustomCommandClass extends Command
{
    public function __construct(
        \Magento\Framework\App\State $state,
    ) {
        $this->_appState = $appState;
        parent::__construct();
    }

    ...

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->_appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); //SET CURRENT AREA

        ...

    }

    ...

}

Note that we do not make use of the Object Manager and that the area has to be set within the function requiring it and NOT in the constructor. This is the official way of setting the area and it should work flawlessly with all Magento 2 versions.


A list of the available areas is available in the following class:

Magento\Framework\App\Area

class Area implements \Magento\Framework\App\AreaInterface
{
    const AREA_GLOBAL = 'global';
    const AREA_FRONTEND = 'frontend';
    const AREA_ADMIN    = 'admin';
    const AREA_ADMINHTML = 'adminhtml';
    const AREA_DOC = 'doc';
    const AREA_CRONTAB = 'crontab';
    const AREA_WEBAPI_REST = 'webapi_rest';
    const AREA_WEBAPI_SOAP = 'webapi_soap';

    ...

As CLI in Magento doesn't have an appropriate area, I figured out the following workaround:

app/code/NameSpace/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- Add this for sending email via cli -->
    <type name="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints">
        <arguments>
            <argument name="debugHintsPath" xsi:type="string">dev/debug/template_hints_storefront</argument>
        </arguments>
    </type>
</config>