state – 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.