Error pertaining a module submission on the Marketplace. Failing the Technical Review.
Report.json file provided after a technical submission over Magento Marketplace doesn’t help me to determine the root of the issue, so it was escalated internally via Magento Engineering team over at their Slack channel. I strongly advise any Dev to join this community specially if you’re struggling with isolated bugs in Magento. StackExchange will have you running in circles with false solutions that only make the matter lengthy.
Tldr: Join the Slack and get pointed in the right direction
Let’s understand the root of the problem.
Installation & Varnish Test seems to be failing. To this day, MFTF isn’t mandatory to include with the module, but will probably be a requirement in the future.

Viewing the Report shows the following environment failing: PHP 7.3 Magento 2.3.6-p1 ce
Although it doesn’t make sense how the EE version passes with no errors, but CE doesn’t. It’s safe to assume it’s an incoherent requirement.

Downloading the Report file we’re presented with unhelpful information. Here’s an excerpt, it seems everything is okay and no complaints about why installation is failing for Magento version 2.3.6-p1.
{"tool":"varnish","status":"FAIL","reports":[{"php_version":"7.3","magento_platform":"M2","magento_edition":"ce","magento_version":"2.3.6-p1","tool":"varnish","vendor":"maurisource","extension":"lightspeed","version":"1.3.62","platform":"m2","magento_cloud_docker":"1.2.1","status":"FAIL","date":"2021-05-04T20:52:29Z","details":{"exit_code":1,"commands":[{"command":"composerConfigRepository0","output":"Finished with the \"0\" exit code."},{"command":"composerConfigKeys0","output":"Finished with the \"0\" exit code."},{"command":"echo \"127.0.0.1 magento2.docker\" >> \/etc\/hosts","output":"Finished with the \"0\" exit code. Process output: \"\"."},{"command":"cp \/usr\/share\/eqp\/VarnishMftfTool\/etc\/varnish-config\/magento-fixtures-profile.xml \/usr\/share\/eqp-varnish-mftf\/magento\/magento-fixtures-profile.xml","output":"Finished with the \"0\" exit code. Process output: \"\"."},
My thought at this point: if it’s not complaining how to troubleshoot? So I try to replicate the Cloud Docker environment locally and deploy Maurisource/Lightspeed module onto it.
Installation went on fine, no complaints at all again. So the issue seems specifically tied to the Marketplace automated testing pipeline. There’s no way for me to know for sure what’s going on in there. So I jumped onto their Slack channel and Serhii Litviachenko from Adobe was kind enough to double check my submission ID and had a helpful hint of underlying issue.
Breaking point
This is where the failure happens. Before the sample data installation
magento-command setup:performance:generate-fixtures ./magento-fixtures-profile.xml
Furthermore, it was found: maurisource/lightspeed:1.3.62
Disabling Maurisource\Lightspeed\Console\Command\LsSyncAll helped to install the extension.
Now we’re going somewhere. It seems that command class is breaking the Installation!
Commenting out the following portion from dependency injection allows the module to pass the Technical Test. Now we’ve determined that \Console\Command seems to be the culprit.
- <type name="Magento\Framework\Console\CommandList">
- <arguments>
- <argument name="commands" xsi:type="array">
- <item name="LsSyncAll" xsi:type="object">Maurisource\Lightspeed\Console\Command\LsSyncAll</item>
- <item name="LsSyncManufacturer" xsi:type="object">LsSyncManufacturer</item>
- <item name="LsSyncCategory" xsi:type="object">LsSyncCategory</item>
- <item name="LsSyncProduct" xsi:type="object">LsSyncProduct</item>
- <item name="LsSyncConfigurable" xsi:type="object">LsSyncConfigurable</item>
- <item name="LsSyncAttribute" xsi:type="object">LsSyncAttribute</item>
- </argument>
- </arguments>
Solution
Proposed solution by Serhii Litviachenko is to use Magento Proxies.
Magento has a solution for this situation: proxies. Proxies extend other classes to become lazy-loaded versions of them. That is, a real instance of the class a proxy extends is created only after one of the class’s methods is actually called. A proxy implements the same interface as the original class and so can be used as a dependency anywhere the original class can. Unlike its parent, a proxy has only one dependency: the object manager.
https://devdocs.magento.com/guides/v2.4/extension-dev-guide/proxies.html#proxies-are-generated-code
Shortly put: We need to Lazy load the Class “LsSyncAll” and its dependencies
Long explanation:
Magento needs to build a list of available CLI commands before running any of them (need a confirmation from the core Magento team though), during that process Magento instantiates CLI commands, and if they have some dependencies that aren’t fully initialized yet like Magento\Framework\App\State, such exceptions could be thrown. We can try to substitute such dependencies with proxies.
Serhii Litviachenko
Fixing the issue
With this knowledge, we can now implement the changes in our Dependency Injection file (di.xml)
First thing to do in our Class file is to determine the various dependencies.
namespace Maurisource\Lightspeed\Console\Command;
use Magento\Framework\App\Area;
use Magento\Framework\App\State;
use Maurisource\Lightspeed\Api\LightspeedServiceInterface;
use Maurisource\Lightspeed\Helper\Data as Helper;
use Maurisource\Lightspeed\Helper\Lock as LockHelper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class LsSyncAll extends Command
We can safely assume that vendor Magento\ and \Maurisource will need to use proxies (5 total in this scenario). Vendor Symfony\ can be left out as it’s not relevant. We can also test individually to determine exactly which dependency is failing, but in my own opinion: it’s okay to Proxy all console commands, since it’s useless to have it instantiated during module installation and create much overhangs.
Let’s open up the di.xml file and after my original existing type I’ve added a new type name for my class LsSyncAll
<type name="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="LsSyncAll" xsi:type="object">Maurisource\Lightspeed\Console\Command\LsSyncAll</item>
<item name="LsSyncManufacturer" xsi:type="object">LsSyncManufacturer</item>
<item name="LsSyncCategory" xsi:type="object">LsSyncCategory</item>
<item name="LsSyncProduct" xsi:type="object">LsSyncProduct</item>
<item name="LsSyncConfigurable" xsi:type="object">LsSyncConfigurable</item>
<item name="LsSyncAttribute" xsi:type="object">LsSyncAttribute</item>
</argument>
</arguments>
</type>
<type name="Maurisource\Lightspeed\Console\Command\LsSyncAll">
</type>
Next I add the arguments for our 5 dependency classes, followed by \Proxy
<type name="Maurisource\Lightspeed\Console\Command\LsSyncAll">
<arguments>
<argument name="lightspeedService" xsi:type="object">Maurisource\Lightspeed\Api\LightspeedServiceInterface\Proxy</argument>
<argument name="state" xsi:type="object">Magento\Framework\App\State\Proxy</argument>
<argument name="area" xsi:type="object">Magento\Framework\App\Area\Proxy</argument>
<argument name="helper" xsi:type="object">Maurisource\Lightspeed\Helper\Data\Proxy</argument>
<argument name="lockHelper" xsi:type="object">Maurisource\Lightspeed\Helper\Lock\Proxy</argument>
</arguments>
</type>
Testing
Running bin/magento setup:upgrade and executing one of my CLI command I can observe that: generated/code/Maurisource/Lightspeed now shows my classes as Proxy.

The same Proxy should be generated and observed for /Magento/Framework
Conclusion
Implementing Proxy for our Console/Command class, helps the module Submission Maurisource/Lightspeed to the Marketplace.

I guess all I need to do now is work on MFTF approval! :-)