inventory
inventory copied to clipboard
can't change/edit SKU of any products with a source assigned
Preconditions (*)
- 2.4.3 multiple sources enabled in MSI
- product with an SKU and a source assigned
Steps to reproduce (*)
- with a source assigned, change the SKU of the product by 1 letter/number and hit save
Expected result (*)
- product saves, reloads with the amended SKU
Actual result (*)
- error code drops, on production it mentioned logs in the exception logs, but nothing appears
- on development the following error and stack trace
TypeError: Argument 1 passed to Magento\InventoryConfiguration\Model\IsSourceItemManagementAllowedForProductType\Interceptor::execute() must be of the type string, null given, called in /var/www/firetoys-sand7/public_html/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php on line 108 and defined in /var/www/firetoys-sand7/public_html/generated/code/Magento/InventoryConfiguration/Model/IsSourceItemManagementAllowedForProductType/Interceptor.php:20
Temp Workaround (*)
- unassign all sources from the product
- change the SKU, and save
- reassign the sources and reset the stocks
obviously this workaround won't work for any product that's live and could potentially have sales, but for new products that need amending before launch it works ok.
Hi @IanFiretoys. Thank you for your report. To speed up processing of this issue, make sure that you provided sufficient information.
Add a comment to assign the issue: @magento I am working on this
- Join Magento Community Engineering Slack and ask your questions in #github channel.
I can confirm its also on Magento 2.4.3-p1 and the workaround pointed out by @IanFiretoys is working fine. See my full stack trace:
main.CRITICAL: TypeError: Argument 1 passed to Magento\InventoryConfiguration\Model\IsSourceItemManagementAllowedForProductType\Interceptor::execute() must be of the type string, null given, called in /var/www/magento2/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php on line 108 and defined in /var/www/magento2/generated/code/Magento/InventoryConfiguration/Model/IsSourceItemManagementAllowedForProductType/Interceptor.php:20
Stack trace:
#0 /var/www/magento2/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php(108): Magento\InventoryConfiguration\Model\IsSourceItemManagementAllowedForProductType\Interceptor->execute()
#1 /var/www/magento2/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php(75): Magento\InventorySales\Model\GetProductSalableQty->validateProductType()
#2 /var/www/magento2/vendor/bsscommerce/inventory-report/Helper/StorageReport.php(137): Magento\InventorySales\Model\GetProductSalableQty->execute()
#3 /var/www/magento2/vendor/bsscommerce/inventory-report/Observer/SaveObserver.php(108): Bss\InventoryReport\Helper\StorageReport->getSaleableQtyByStockId()
#4 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(88): Bss\InventoryReport\Observer\SaveObserver->execute()
#5 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(74): Magento\Framework\Event\Invoker\InvokerDefault->_callObserverMethod()
#6 /var/www/magento2/vendor/magento/framework/Event/Manager.php(66): Magento\Framework\Event\Invoker\InvokerDefault->dispatch()
#7 /var/www/magento2/generated/code/Magento/Framework/Event/Manager/Proxy.php(95): Magento\Framework\Event\Manager->dispatch()
#8 /var/www/magento2/vendor/magento/framework/Model/AbstractModel.php(702): Magento\Framework\Event\Manager\Proxy->dispatch()
#9 /var/www/magento2/vendor/magento/module-catalog/Model/AbstractModel.php(383): Magento\Framework\Model\AbstractModel->beforeSave()
#10 /var/www/magento2/vendor/magento/module-catalog/Model/Product.php(934): Magento\Catalog\Model\AbstractModel->beforeSave()
#11 /var/www/magento2/generated/code/Magento/Catalog/Model/Product/Interceptor.php(230): Magento\Catalog\Model\Product->beforeSave()
#12 /var/www/magento2/vendor/magento/framework/EntityManager/Observer/BeforeEntitySave.php(34): Magento\Catalog\Model\Product\Interceptor->beforeSave()
#13 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(88): Magento\Framework\EntityManager\Observer\BeforeEntitySave->execute()
#14 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(74): Magento\Framework\Event\Invoker\InvokerDefault->_callObserverMethod()
#15 /var/www/magento2/vendor/magento/framework/Event/Manager.php(66): Magento\Framework\Event\Invoker\InvokerDefault->dispatch()
#16 /var/www/magento2/generated/code/Magento/Framework/Event/Manager/Proxy.php(95): Magento\Framework\Event\Manager->dispatch()
#17 /var/www/magento2/vendor/magento/framework/EntityManager/EventManager.php(51): Magento\Framework\Event\Manager\Proxy->dispatch()
#18 /var/www/magento2/vendor/magento/framework/EntityManager/Operation/Update.php(106): Magento\Framework\EntityManager\EventManager->dispatchEntityEvent()
#19 /var/www/magento2/vendor/magento/framework/EntityManager/EntityManager.php(106): Magento\Framework\EntityManager\Operation\Update->execute()
#20 /var/www/magento2/vendor/magento/module-catalog/Model/ResourceModel/Product.php(773): Magento\Framework\EntityManager\EntityManager->save()
#21 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Model\ResourceModel\Product->save()
#22 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Model\ResourceModel\Product\Interceptor->___callParent()
#23 /var/www/magento2/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product.php(58): Magento\Catalog\Model\ResourceModel\Product\Interceptor->Magento\Framework\Interception\{closure}()
#24 /var/www/magento2/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product.php(28): Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin\Product->addCommitCallback()
#25 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin\Product->aroundSave()
#26 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Model\ResourceModel\Product\Interceptor->Magento\Framework\Interception\{closure}()
#27 /var/www/magento2/generated/code/Magento/Catalog/Model/ResourceModel/Product/Interceptor.php(32): Magento\Catalog\Model\ResourceModel\Product\Interceptor->___callPlugins()
#28 /var/www/magento2/vendor/magento/framework/Model/AbstractModel.php(655): Magento\Catalog\Model\ResourceModel\Product\Interceptor->save()
#29 /var/www/magento2/generated/code/Magento/Catalog/Model/Product/Interceptor.php(1706): Magento\Framework\Model\AbstractModel->save()
#30 /var/www/magento2/vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php(143): Magento\Catalog\Model\Product\Interceptor->save()
#31 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Controller\Adminhtml\Product\Save->execute()
#32 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callParent()
#33 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->Magento\Framework\Interception\{closure}()
#34 /var/www/magento2/generated/code/Magento/Catalog/Controller/Adminhtml/Product/Save/Interceptor.php(23): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callPlugins()
#35 /var/www/magento2/vendor/magento/framework/App/Action/Action.php(111): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->execute()
#36 /var/www/magento2/vendor/magento/module-backend/App/AbstractAction.php(151): Magento\Framework\App\Action\Action->dispatch()
#37 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Backend\App\AbstractAction->dispatch()
#38 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callParent()
#39 /var/www/magento2/vendor/magento/module-backend/App/Action/Plugin/Authentication.php(143): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->Magento\Framework\Interception\{closure}()
#40 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch()
#41 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->Magento\Framework\Interception\{closure}()
#42 /var/www/magento2/generated/code/Magento/Catalog/Controller/Adminhtml/Product/Save/Interceptor.php(32): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callPlugins()
#43 /var/www/magento2/vendor/magento/framework/App/FrontController.php(245): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->dispatch()
#44 /var/www/magento2/vendor/magento/framework/App/FrontController.php(212): Magento\Framework\App\FrontController->getActionResponse()
#45 /var/www/magento2/vendor/magento/framework/App/FrontController.php(147): Magento\Framework\App\FrontController->processRequest()
#46 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch()
#47 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent()
#48 /var/www/magento2/vendor/m2e/ebay-amazon-magento2/Plugin/HealthStatus/Magento/Framework/App/FrontController.php(81): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}()
#49 /var/www/magento2/vendor/m2e/ebay-amazon-magento2/Plugin/AbstractPlugin.php(45): Ess\M2ePro\Plugin\HealthStatus\Magento\Framework\App\FrontController->processDispatch()
#50 /var/www/magento2/vendor/m2e/ebay-amazon-magento2/Plugin/HealthStatus/Magento/Framework/App/FrontController.php(45): Ess\M2ePro\Plugin\AbstractPlugin->execute()
#51 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Ess\M2ePro\Plugin\HealthStatus\Magento\Framework\App\FrontController->aroundDispatch()
#52 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}()
#53 /var/www/magento2/generated/code/Magento/Framework/App/FrontController/Interceptor.php(23): Magento\Framework\App\FrontController\Interceptor->___callPlugins()
#54 /var/www/magento2/vendor/magento/framework/App/Http.php(116): Magento\Framework\App\FrontController\Interceptor->dispatch()
#55 /var/www/magento2/generated/code/Magento/Framework/App/Http/Interceptor.php(23): Magento\Framework\App\Http->launch()
#56 /var/www/magento2/vendor/magento/framework/App/Bootstrap.php(264): Magento\Framework\App\Http\Interceptor->launch()
#57 /var/www/magento2/pub/index.php(374): Magento\Framework\App\Bootstrap->run()
#58 {main} [] []
I can confirm its also on Magento 2.4.3-p1 and the workaround pointed out by @IanFiretoys is working fine. See my full stack trace:
main.CRITICAL: TypeError: Argument 1 passed to Magento\InventoryConfiguration\Model\IsSourceItemManagementAllowedForProductType\Interceptor::execute() must be of the type string, null given, called in /var/www/magento2/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php on line 108 and defined in /var/www/magento2/generated/code/Magento/InventoryConfiguration/Model/IsSourceItemManagementAllowedForProductType/Interceptor.php:20 Stack trace: #0 /var/www/magento2/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php(108): Magento\InventoryConfiguration\Model\IsSourceItemManagementAllowedForProductType\Interceptor->execute() #1 /var/www/magento2/vendor/magento/module-inventory-sales/Model/GetProductSalableQty.php(75): Magento\InventorySales\Model\GetProductSalableQty->validateProductType() #2 /var/www/magento2/vendor/bsscommerce/inventory-report/Helper/StorageReport.php(137): Magento\InventorySales\Model\GetProductSalableQty->execute() #3 /var/www/magento2/vendor/bsscommerce/inventory-report/Observer/SaveObserver.php(108): Bss\InventoryReport\Helper\StorageReport->getSaleableQtyByStockId() #4 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(88): Bss\InventoryReport\Observer\SaveObserver->execute() #5 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(74): Magento\Framework\Event\Invoker\InvokerDefault->_callObserverMethod() #6 /var/www/magento2/vendor/magento/framework/Event/Manager.php(66): Magento\Framework\Event\Invoker\InvokerDefault->dispatch() #7 /var/www/magento2/generated/code/Magento/Framework/Event/Manager/Proxy.php(95): Magento\Framework\Event\Manager->dispatch() #8 /var/www/magento2/vendor/magento/framework/Model/AbstractModel.php(702): Magento\Framework\Event\Manager\Proxy->dispatch() #9 /var/www/magento2/vendor/magento/module-catalog/Model/AbstractModel.php(383): Magento\Framework\Model\AbstractModel->beforeSave() #10 /var/www/magento2/vendor/magento/module-catalog/Model/Product.php(934): Magento\Catalog\Model\AbstractModel->beforeSave() #11 /var/www/magento2/generated/code/Magento/Catalog/Model/Product/Interceptor.php(230): Magento\Catalog\Model\Product->beforeSave() #12 /var/www/magento2/vendor/magento/framework/EntityManager/Observer/BeforeEntitySave.php(34): Magento\Catalog\Model\Product\Interceptor->beforeSave() #13 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(88): Magento\Framework\EntityManager\Observer\BeforeEntitySave->execute() #14 /var/www/magento2/vendor/magento/framework/Event/Invoker/InvokerDefault.php(74): Magento\Framework\Event\Invoker\InvokerDefault->_callObserverMethod() #15 /var/www/magento2/vendor/magento/framework/Event/Manager.php(66): Magento\Framework\Event\Invoker\InvokerDefault->dispatch() #16 /var/www/magento2/generated/code/Magento/Framework/Event/Manager/Proxy.php(95): Magento\Framework\Event\Manager->dispatch() #17 /var/www/magento2/vendor/magento/framework/EntityManager/EventManager.php(51): Magento\Framework\Event\Manager\Proxy->dispatch() #18 /var/www/magento2/vendor/magento/framework/EntityManager/Operation/Update.php(106): Magento\Framework\EntityManager\EventManager->dispatchEntityEvent() #19 /var/www/magento2/vendor/magento/framework/EntityManager/EntityManager.php(106): Magento\Framework\EntityManager\Operation\Update->execute() #20 /var/www/magento2/vendor/magento/module-catalog/Model/ResourceModel/Product.php(773): Magento\Framework\EntityManager\EntityManager->save() #21 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Model\ResourceModel\Product->save() #22 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Model\ResourceModel\Product\Interceptor->___callParent() #23 /var/www/magento2/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product.php(58): Magento\Catalog\Model\ResourceModel\Product\Interceptor->Magento\Framework\Interception\{closure}() #24 /var/www/magento2/vendor/magento/module-catalog-search/Model/Indexer/Fulltext/Plugin/Product.php(28): Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin\Product->addCommitCallback() #25 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin\Product->aroundSave() #26 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Model\ResourceModel\Product\Interceptor->Magento\Framework\Interception\{closure}() #27 /var/www/magento2/generated/code/Magento/Catalog/Model/ResourceModel/Product/Interceptor.php(32): Magento\Catalog\Model\ResourceModel\Product\Interceptor->___callPlugins() #28 /var/www/magento2/vendor/magento/framework/Model/AbstractModel.php(655): Magento\Catalog\Model\ResourceModel\Product\Interceptor->save() #29 /var/www/magento2/generated/code/Magento/Catalog/Model/Product/Interceptor.php(1706): Magento\Framework\Model\AbstractModel->save() #30 /var/www/magento2/vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php(143): Magento\Catalog\Model\Product\Interceptor->save() #31 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Controller\Adminhtml\Product\Save->execute() #32 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callParent() #33 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->Magento\Framework\Interception\{closure}() #34 /var/www/magento2/generated/code/Magento/Catalog/Controller/Adminhtml/Product/Save/Interceptor.php(23): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callPlugins() #35 /var/www/magento2/vendor/magento/framework/App/Action/Action.php(111): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->execute() #36 /var/www/magento2/vendor/magento/module-backend/App/AbstractAction.php(151): Magento\Framework\App\Action\Action->dispatch() #37 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Backend\App\AbstractAction->dispatch() #38 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callParent() #39 /var/www/magento2/vendor/magento/module-backend/App/Action/Plugin/Authentication.php(143): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->Magento\Framework\Interception\{closure}() #40 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch() #41 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->Magento\Framework\Interception\{closure}() #42 /var/www/magento2/generated/code/Magento/Catalog/Controller/Adminhtml/Product/Save/Interceptor.php(32): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->___callPlugins() #43 /var/www/magento2/vendor/magento/framework/App/FrontController.php(245): Magento\Catalog\Controller\Adminhtml\Product\Save\Interceptor->dispatch() #44 /var/www/magento2/vendor/magento/framework/App/FrontController.php(212): Magento\Framework\App\FrontController->getActionResponse() #45 /var/www/magento2/vendor/magento/framework/App/FrontController.php(147): Magento\Framework\App\FrontController->processRequest() #46 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch() #47 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent() #48 /var/www/magento2/vendor/m2e/ebay-amazon-magento2/Plugin/HealthStatus/Magento/Framework/App/FrontController.php(81): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() #49 /var/www/magento2/vendor/m2e/ebay-amazon-magento2/Plugin/AbstractPlugin.php(45): Ess\M2ePro\Plugin\HealthStatus\Magento\Framework\App\FrontController->processDispatch() #50 /var/www/magento2/vendor/m2e/ebay-amazon-magento2/Plugin/HealthStatus/Magento/Framework/App/FrontController.php(45): Ess\M2ePro\Plugin\AbstractPlugin->execute() #51 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Ess\M2ePro\Plugin\HealthStatus\Magento\Framework\App\FrontController->aroundDispatch() #52 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() #53 /var/www/magento2/generated/code/Magento/Framework/App/FrontController/Interceptor.php(23): Magento\Framework\App\FrontController\Interceptor->___callPlugins() #54 /var/www/magento2/vendor/magento/framework/App/Http.php(116): Magento\Framework\App\FrontController\Interceptor->dispatch() #55 /var/www/magento2/generated/code/Magento/Framework/App/Http/Interceptor.php(23): Magento\Framework\App\Http->launch() #56 /var/www/magento2/vendor/magento/framework/App/Bootstrap.php(264): Magento\Framework\App\Http\Interceptor->launch() #57 /var/www/magento2/pub/index.php(374): Magento\Framework\App\Bootstrap->run() #58 {main} [] []
I have recently found this is related to a 3rd party extension, can you confirm if you have the bss inventory report extension installed?
@IanFiretoys yes I have installed BSS Inventory report, latest version 1.1.6 see its also included in my stack trace line 2 and 3. The extension also causes other problems with Magento 2.4.3 like this here: https://support.bsscommerce.com/support/solutions/articles/19000133595-v1-1-6-how-to-fix-error-registry-key-bss-salable-qty-before-already-exists-
Can you confirm its fixed with the extension disabled? If yes, its worth a bug report to BSS Commerce, what do you think?
it is confirmed to work without the extension, this issue also cropped up and the cause was the bss inventory report not dealing with getSaleableQuantity properly. https://github.com/magento/magento2/issues/35257#issuecomment-1089872925
Outch, looks like this Extension is really buggy and its worth thinking about how to replace it …
I sent a bugreport to BSS Commerce, basically this makes it not being compatible for Magento 2.4. – lets hope they fix it.
yep, same, if anyone can suggest an alternative stock history extension i'm all ears
The Plugin provider made a fix and published it: https://bsscommerce.freshdesk.com/support/solutions/articles/19000135701
Working for me. I know no other alternate stock history module, I guess most others rely on external stock management solutions and not 100% on MSI only – imho the stock tracking&history / reporting function should be Magento core anyway to give MSI the "next level". We will see ;-)