42

I'm getting following error while updating data through CustomerRepositoryInterface

[Magento\Framework\Exception\SessionException]  
Area code not set: Area code must be set before starting a session.

[Magento\Framework\Exception\LocalizedException]  
Area code is not set                              

Following is my di.xml file

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="test1_command" xsi:type="object">Test\Module\Console\Command\Test1Command</item>
                <item name="test2_command" xsi:type="object">Test\Module\Console\Command\Test2Command</item>
            </argument>
        </arguments>
    </type>
</config>
  • Could you please show more of your code and give more context as to what you are trying to do? – Nathan Toombs Jan 11 '16 at 18:06
  • I'm encountering the same issue. However the solution shown above does not work for me. This has been perplexing me for weeks now. – Stevenlavine Jul 4 '17 at 6:27

10 Answers 10

61

The area is not set in Magento CLI (it is not required for any core commands). It can be set at the beginning of your command's execute method:

/** @var \Magento\Framework\App\State **/
private $state;

public function __construct(\Magento\Framework\App\State $state) {
    $this->state = $state;
    parent::__construct();
}

public function execute() {
    $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_FRONTEND); // or \Magento\Framework\App\Area::AREA_ADMINHTML, depending on your needs
}
  • 5
    FYI, you "adminhtml" was not working for me. "admin" worked. – Phoenix128_RiccardoT Jun 8 '16 at 8:31
  • For me it doesn't work (admin or adminhtml) - there is an error: Area code already set. But then, if I comment it out there is exception from subject again. – Bartosz Kubicki Jul 15 '16 at 10:11
  • 13
    You should use \Magento\Framework\App\Area::AREA_* constants instead of hardcoded strings – 7ochem May 11 '17 at 11:44
  • 2
    It's best not to set the area code in your constructor; whenever you run bin/magento all the constructors are executed, and if the area code is tried to be set 2 times an exception is thrown. It's better to set the area code in your execute()-method, or run your code in store- or area emulation if state is required. Also: constructor dependencies that could trigger a session down the chain should be initialized using a factory or a proxy to prevent dependencies from setting an area code. – Giel Berkers Mar 2 '18 at 7:33
  • 1
    Please unset it as a correct answer. It creates exception when we set area code in constructor. – Sandipan S Mar 26 '18 at 11:54
32

I've stumbled into this problem again today and it's important to know that this problem is thrown whenever a dependency down the chain initiates an instance that needs to know the state of the application.

In many cases this error is session-bound (since the session needs to know the state of the application (frontend or adminhtml)).

In my case I needed to have Magento\Tax\Api\TaxCalculationInterface in a CLI command, but this requires at some point in it's dependency chain the customer session (probably to get the customer group).

Edit: I found a better solution using proxies. But for histories' sake, here's my previous answer:


To solve this I did not include this interface in my constructor, but rather it's factory:

/**
 * @var \Magento\Tax\Api\TaxCalculationInterfaceFactory
 */
protected $taxCalculationFactory;

/**
 * @param \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
 */
public function __construct(
    \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
) {
    $this->taxCalculationFactory = $taxCalculationFactory;
}

This way, the class is only instantiated in the one method where I needed it, and no longer in the constructor:

$taxCalculation = $this->taxCalculationFactory->create();

This solved the problem for me in this particular case.


And now the answer using a proxy:

If you don't want to trigger all the dependencies down the chain, you should use a proxy in your constructor. According to the original documentation:

... constructor injection also means that a chain reaction of object instantiation is often the result when you create an object.

and:

... Proxies extend other classes to become lazy-loaded versions of them. That is, a real instance of the class a proxy extends created only after one of the class’s methods is actually called.

So in my situation, with the TaxCalculationInterface, all I had to do was instantiate my tax calculation as a proxy in my constructor:

/**
 * @var \Magento\Tax\Api\TaxCalculationInterface\Proxy
 */
protected $taxCalculation;

/**
 * @param \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
 */
public function __construct(
    \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
) {
    $this->taxCalculation = $taxCalculation;
}

This way, my class is lazy loaded. That is: it's only instantiated as soon as I call one of it's methods. For example:

$rate = $this->taxCalculation->getCalculatedRate($productRateId);
17

You shouldn't use setAreaCode in the __construct for CLI commands. When you run any command Magento collect and create instance for each script registered in your application. If there are more than one __construct with area code definition you will have the error.

I suppose better to use the execute() method to set area code. Check the catalog module: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php

  • 1
    Makes sense to me. Anyone else wants to add a comment on this? – ermannob Jan 3 '17 at 17:05
  • This is correct, see also my comment on the accepted answer: It's best not to set the area code in your constructor; whenever you run bin/magento all the constructors are executed, and if the area code is tried to be set 2 times an exception is thrown. It's better to set the area code in your execute()-method, or run your code in store- or area emulation if state is required. Also: constructor dependencies that could trigger a session down the chain should be initialized using a factory or a proxy to prevent dependencies from setting an area code. – Giel Berkers Mar 2 '18 at 7:33
  • but in Magento 2.2, injecting \Magento\Sales\Api\Data\OrderInterface or \Magento\Sales\Api\OrderManagementInterface in command class constructs will call Magento\Framework\Session\SessionManager->__construct() and will end up "area not set". This doesn't happen 2.1. because module-ui/Config/Reader/Definition/Data is introduced in 2.2 how do we solve this? – Doni Wibowo Jan 15 at 7:51
5

for this areaCode issue, if the 'frontend' parameter is not working, try :

$this->_state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);

was working for me, hope it helps

  • In which file should I add this code? I have exactly the same problem. – Magento Learner Apr 3 '18 at 7:43
  • @xxx I had this problem from a custom command, so I wrote this in the command file I created. You can add it in the execute function, with something like : try { $this->_state->... } finally { $this->executeMyCommand() } – DependencyHell Apr 3 '18 at 9:29
3

In most cases exception is caused by some actions performed in console command. Solution (instead of setting area code) is to emulate area code and perform action using

$this->state->emulateAreaCode(Area::AREA_ADMINHTML, [$this, 'someAction'], []);

where $state is object of Magento\Framework\App\State. Setting area in different place is a problem, because it can cause conflict between calls.

  • I am using this reference and getting the similar error Area code is already set in my controller, can you please help me to get out of this. I have made changes like, calling setareacode in my construct function but getting same error. – LAW Feb 21 '18 at 8:22
2

The problem is that it does not have any method that returns false if the variable area_code has not been set. The way I found it to solve was by creating override of the state class and creating a new method to validate if the area_code was set.

In my file di.xml

    <preference for="Magento\Framework\App\State" type="Webjump\Abacos\App\State" />

Createad file Webjump\Abacos\App\State

namespace Webjump\Abacos\App;

class State extends \Magento\Framework\App\State
{
    public function validateAreaCode()
    {
        if (!isset($this->_areaCode)) {
            return false;
        }
        return true;
    }
}

Use

/**
* @var \Magento\Framework\App\State
*/
protected $state;

public function __construct(
            \Magento\Framework\App\State $state
)
{
$this->state = $state;
if (!$this->state->validateAreaCode()) {
 $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML);
}
}
1

In magento 2 if you set AreadCode but still get this error then please try following code.

  • Use Magento\Framework\App\Bootstrap;
  • include app/bootstrap.php;
  • $bootstrap = Bootstrap::create(BP, $_SERVER);
  • $objectManager = $bootstrap->getObjectManager();
  • $state = $objectManager->get('Magento\Framework\App\State');
  • $state->setAreaCode('global');
0

I was suffering of error 'Area code is not set' running bin/magento setup:upgrade after import database from production. It's a little bit different case than this topic subject, but maybe will help someone. I was able to resolve this issue locally running bin/magento deploy:mode:set developer despite I already was in developer mode. Magento did some configuration adjustments, specially for me debug_logging played role.

-1

I have found same issue with Area code while setup upgrade.

Module 'Magento_WebsiteRestriction':Installing data... Area code not set: Area code must be set before starting a session

I have disabled all third party modules and run setup:upgrade

Then I have re-enabled all of third party modules and run same command. Problem is solved for me Hope this is help for you.

  • this is not actually a solution. It's just hiding the dirt under the rug. But good find anyway. It should help during the development process, but it does not make the problem go away. – Marius Jun 25 '18 at 8:13
  • Thank you Marius for correcting me. I have find the same case in most of my project and this help me to resolve this. – Ravi yadav Jun 25 '18 at 8:15
  • @Marius, would you care to explain why, and let people know the most canonical method to resolve the issue? – chrBrd Nov 17 '18 at 18:16
-1

Try to upgrade magento using CLI than i found 'area code not define' for session & app.But i can't find which module or theme.so i just do below changes in vendor/magento/framework/App/State.php file & it's working.

public function __construct(
    \Magento\Framework\Config\ScopeInterface $configScope,
    $mode = self::MODE_DEFAULT
) {
    $this->_areaCode = Area::AREA_GLOBAL;
    $this->_configScope = $configScope;
    switch ($mode) {
        ...
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.