Zend certified PHP/Magento developer

Magento 2.3 -> 2.4: CLI commands all throw “Area code is not set”

The story so far:
I’m updating Magento from 2.3 to 2.4 and in doing so I’m now getting an “Area code is not set” when running any CLI command. This did not happen in 2.3 and after looking at the following stack trace from bin/magento s:di:c –verbose I have the following stack trace:

In State.php line 153:
[MagentoFrameworkExceptionLocalizedException]  
Area code is not set                              
Exception trace:
at /var/www/OUR_COMPANY/vendor/magento/framework/App/State.php:153
MagentoFrameworkAppState->getAreaCode() at /var/www/OUR_COMPANY/generated/code/Magento/Framework/App/State/Interceptor.php:50
MagentoFrameworkAppStateInterceptor->getAreaCode() at /var/www/OUR_COMPANY/vendor/magento/module-theme/Model/Theme.php:272
MagentoThemeModelTheme->getArea() at /var/www/OUR_COMPANY/vendor/magento/framework/View/File/Collector/Base.php:68
MagentoFrameworkViewFileCollectorBase->getFiles() at /var/www/OUR_COMPANY/vendor/magento/framework/View/File/Collector/Decorator/ModuleOutput.php:59
MagentoFrameworkViewFileCollectorDecoratorModuleOutput->getFiles() at /var/www/OUR_COMPANY/vendor/magento/framework/View/File/Collector/Decorator/ModuleDependency.php:63
MagentoFrameworkViewFileCollectorDecoratorModuleDependency->getFiles() at /var/www/OUR_COMPANY/vendor/magento/framework/View/Layout/File/Collector/Aggregated.php:88
MagentoFrameworkViewLayoutFileCollectorAggregated->getFiles() at /var/www/OUR_COMPANY/vendor/magento/framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php:76
MagentoFrameworkViewElementUiComponentConfigFileCollectorAggregatedFileCollector->collectFiles() at /var/www/OUR_COMPANY/vendor/magento/module-ui/Config/Reader/FileResolver.php:43
MagentoUiConfigReaderFileResolver->get() at /var/www/OUR_COMPANY/vendor/magento/module-ui/Config/Reader/Definition.php:28
MagentoUiConfigReaderDefinition->read() at /var/www/OUR_COMPANY/vendor/magento/module-ui/Config/Reader/Definition/Data.php:89
MagentoUiConfigReaderDefinitionData->initData() at /var/www/OUR_COMPANY/vendor/magento/module-ui/Config/Reader/Definition/Data.php:75
MagentoUiConfigReaderDefinitionData->__construct() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:121
MagentoFrameworkObjectManagerFactoryAbstractFactory->createObject() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:66
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:170
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:170
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:206
MagentoFrameworkObjectManagerFactoryAbstractFactory->parseArray() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:182
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:170
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:56
MagentoFrameworkObjectManagerObjectManager->create() at /var/www/OUR_COMPANY/vendor/magento/framework/View/LayoutFactory.php:50
MagentoFrameworkViewLayoutFactory->create() at /var/www/OUR_COMPANY/vendor/magento/module-payment/Helper/Data.php:79
MagentoPaymentHelperData->__construct() at /var/www/OUR_COMPANY/generated/code/Magento/Payment/Helper/Data/Interceptor.php:14
MagentoPaymentHelperDataInterceptor->__construct() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:121
MagentoFrameworkObjectManagerFactoryAbstractFactory->createObject() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:66
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:170
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:170
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:170
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:70
MagentoFrameworkObjectManagerObjectManager->get() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:206
MagentoFrameworkObjectManagerFactoryAbstractFactory->parseArray() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:182
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:276
MagentoFrameworkObjectManagerFactoryAbstractFactory->getResolvedArgument() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:239
MagentoFrameworkObjectManagerFactoryAbstractFactory->resolveArgumentsInRuntime() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:34
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->_resolveArguments() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:59
MagentoFrameworkObjectManagerFactoryDynamicDeveloper->create() at /var/www/OUR_COMPANY/vendor/magento/framework/ObjectManager/ObjectManager.php:56
MagentoFrameworkObjectManagerObjectManager->create() at /var/www/OUR_COMPANY/vendor/magento/framework/Console/Cli.php:153
MagentoFrameworkConsoleCli->getApplicationCommands() at /var/www/OUR_COMPANY/vendor/magento/framework/Console/Cli.php:134
MagentoFrameworkConsoleCli->getDefaultCommands() at /var/www/OUR_COMPANY/vendor/symfony/console/Application.php:1274
SymfonyComponentConsoleApplication->init() at /var/www/OUR_COMPANY/vendor/symfony/console/Application.php:629
SymfonyComponentConsoleApplication->find() at /var/www/OUR_COMPANY/vendor/symfony/console/Application.php:237
SymfonyComponentConsoleApplication->doRun() at /var/www/OUR_COMPANY/vendor/magento/framework/Console/Cli.php:115
MagentoFrameworkConsoleCli->doRun() at /var/www/OUR_COMPANY/vendor/symfony/console/Application.php:149
SymfonyComponentConsoleApplication->run() at /var/www/OUR_COMPANY/bin/magento:23

The stand out line is:

 MagentoThemeModelTheme->getArea() at /var/www/OUR_COMPANY/vendor/magento/framework/View/File/Collector/Base.php:68

When we open up vendor/magento/framework/View/File/Collector/Base.php in 2.3 & 2.4 we see the following:

In 2.4

/**
* Retrieve files
*
* @param MagentoFrameworkViewDesignThemeInterface $theme
* @param string $filePath
* @return MagentoFrameworkViewFile[]
*/
public function getFiles(ThemeInterface $theme, $filePath)
{
$result = [];
$sharedFiles = $this->componentDirSearch->collectFilesWithContext(
ComponentRegistrar::MODULE,
"view/base/{$this->subDir}{$filePath}"
);
foreach ($sharedFiles as $file) {
$result[] = $this->fileFactory->create($file->getFullPath(), $file->getComponentName(), null, true);
}
$area = $theme->getArea(); <-- This line is important
$themeFiles = $this->componentDirSearch->collectFilesWithContext(
ComponentRegistrar::MODULE,
"view/{$area}/{$this->subDir}{$filePath}"
);
foreach ($themeFiles as $file) {
$result[] = $this->fileFactory->create($file->getFullPath(), $file->getComponentName());
}
return $result;
}

In 2.3:

/**
* Retrieve files
*
* @param MagentoFrameworkViewDesignThemeInterface $theme
* @param string $filePath
* @return MagentoFrameworkViewFile[]
*/
public function getFiles(ThemeInterface $theme, $filePath)
{
$result = [];
$sharedFiles = $this->componentDirSearch->collectFilesWithContext(
ComponentRegistrar::MODULE,
"view/base/{$this->subDir}{$filePath}"
);
foreach ($sharedFiles as $file) {
$result[] = $this->fileFactory->create($file->getFullPath(), $file->getComponentName(), null, true);
}
$area = $theme->getData('area'); <-- This line is important
$themeFiles = $this->componentDirSearch->collectFilesWithContext(
ComponentRegistrar::MODULE,
"view/{$area}/{$this->subDir}{$filePath}"
);
foreach ($themeFiles as $file) {
$result[] = $this->fileFactory->create($file->getFullPath(), $file->getComponentName());
}
return $result;
}

The large difference are the corresponding lines:

2.3: $area = $theme->getData('area');
vs
2.4: $area = $theme->getArea();

getArea() will throw a MagentoFrameworkExceptionLocalizedException if the area code is not set, while getData(‘area’) will return null if the area code is not set.

Now I imagine a correct solution is setting the area code appropriately elsewhere. But I haven’t the slightest idea as to where.

My next hunch is to override the class and implement the default behavior of returning null which is what all our 2.3 code would expect. However this is almost certainly not the right path. In addition when I do override vendor/magento/framework/View/File/Collector/Base.php the CLI ignores the override.