I have a magento 2 multi store setup (e.g. stores with the id 1 - 3) and I want to update the name of the category with the entity_id 3.

I've tried

$cat = $this->_categoryRepository->get(3, 3);
$cat->setName('Test in Store 3');

with $this->_categoryRepository being an implementation of Magento\Catalog\Api\CategoryRepositoryInterface obtained via constructor based dependency injection.

But this just updates the value of the current store. I ran this code inside a cli command and it updated the name attribute of store 1 and not store 3.

The save method in Magento\Catalog\Model\CategoryRepository obtains the store via

$storeId = (int)$this->storeManager->getStore()->getId();

which always yields the current store.

What is the correct way to update a store specific attribute of a category? I know I could directly hack the database or use the resource model, but that would totally defeat the purpose of the repository pattern.

  • Review this link to change attribute of category w3solver.com/…. Let me know if that does not help
    – arushi
    May 10, 2017 at 12:49

3 Answers 3


$storeId = (int)$this->storeManager->getStore()->getId(); Category name does have scope of store so repository's save method will work fine when you call this code from admin after switching scope using store scope switcher in admin category form. But instead of using save method of the repository you could
Directly call save on category.


The code you have should work. However, it will only be successful if the category validation process succeeds.

In your circumstance, you do report this code is not successful. I have been using your code today on my system, I had a similar issue.

To resolve it, I went into my backend and I did edit the category i was trying to change, (selecting the same store id), and did update the same field. Then when I did hit save, the backend was returning an error (for me, the required field 'heading' was missing its value)

Then, once you know why the code was not succesfull, you can for instance adjust your code by setting a default value for the required fields that have a value empty.

for me, the solution was to change your code to:

$cat = $this->categoryRepository->get(3, 2);
        $cat->setName('Test in Store 3');
        $cat->setData('heading', 'test'); // this field is a required field in my system

I've used this method. With this I was able to only update the specific value (name) in store level.

                    $categoryModel = $this->_categoryModel->load(5);//5=CategoryId
                    $data = array();
                    foreach ($categoryModel->getAttributes() as $attribute) {
                        if ($attribute->isScopeGlobal() ||
                            $categoryModel->getExistsStoreValueFlag($attribute->getAttributeCode())) {

                    $categoryModel->setIncludeInMenu(null);//To Avoid picking up the store_level value for Include in Menu

Additional Tip: It seems that For the products we can achieve this by Magento\Catalog\Model\ResourceModel\Product\Action class

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.