Magento 1.9.2.1迁移至2.4.6后无法查看/编辑产品的类型错误
Magento 1.9.2.1迁移至2.4.6后产品管理页面类型错误解决方案
问题场景
从Magento 1.9.2.1迁移到2.4.6后,后台查看/编辑产品时触发类型错误,前端也无法展示产品。错误信息如下:
TypeError: Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer::sanitizeComponentMetadata(): Argument #1 ($meta) must be of type array, null given in /var/www/magento2/vendor/magento/framework/View/Element/UiComponent/DataProvider/Sanitizer.php:85 Stack trace: #0 [internal function]: Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer->sanitizeComponentMetadata() #1 /var/www/magento2/vendor/magento/framework/View/Element/UiComponent/DataProvider/Sanitizer.php(97): array_map() #2 [internal function]: Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer->sanitizeComponentMetadata() #3 /var/www/magento2/vendor/magento/framework/View/Element/UiComponent/DataProvider/Sanitizer.php(97): array_map() #4 /var/www/magento2/vendor/magento/framework/View/Element/UiComponentFactory.php(332): Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer->sanitizeComponentMetadata() #5 /var/www/magento2/vendor/magento/framework/View/Element/UiComponentFactory.php(231): Magento\Framework\View\Element\UiComponentFactory->mergeMetadata() #6 /var/www/magento2/vendor/magento/framework/View/Layout/Generator/UiComponent.php(140): Magento\Framework\View\Element\UiComponentFactory->create() #7 /var/www/magento2/vendor/magento/framework/View/Layout/Generator/UiComponent.php(103): Magento\Framework\View\Layout\Generator\UiComponent->generateComponent() #8 /var/www/magento2/vendor/magento/framework/View/Layout/GeneratorPool.php(93): Magento\Framework\View\Layout\Generator\UiComponent->process() #9 /var/www/magento2/vendor/magento/framework/View/Layout.php(365): Magento\Framework\View\Layout\GeneratorPool->process() #10 /var/www/magento2/generated/code/Magento/Framework/View/Layout/Interceptor.php(68): Magento\Framework\View\Layout->generateElements() #11 /var/www/magento2/vendor/magento/framework/View/Layout/Builder.php(129): Magento\Framework\View\Layout\Interceptor->generateElements() #12 /var/www/magento2/vendor/magento/framework/View/Page/Builder.php(65): Magento\Framework\View\Layout\Builder->generateLayoutBlocks() #13 /var/www/magento2/vendor/magento/framework/View/Layout/Builder.php(65): Magento\Framework\View\Page\Builder->generateLayoutBlocks() #14 /var/www/magento2/vendor/magento/framework/View/Layout.php(271): Magento\Framework\View\Layout\Builder->build() #15 /var/www/magento2/vendor/magento/framework/View/Layout.php(896): Magento\Framework\View\Layout->build() #16 /var/www/magento2/generated/code/Magento/Framework/View/Layout/Interceptor.php(293): Magento\Framework\View\Layout->getBlock() #17 /var/www/magento2/vendor/magento/module-backend/Model/View/Result/Page.php(26): Magento\Framework\View\Layout\Interceptor->getBlock() #18 /var/www/magento2/generated/code/Magento/Backend/Model/View/Result/Page/Interceptor.php(23): Magento\Backend\Model\View\Result\Page->setActiveMenu() #19 /var/www/magento2/vendor/magento/module-catalog/Controller/Adminhtml/Product/Edit.php(82): Magento\Backend\Model\View\Result\Page\Interceptor->setActiveMenu() #20 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Controller\Adminhtml\Product\Edit->execute() #21 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->___callParent() #22 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->Magento\Framework\Interception\{closure}() #23 /var/www/magento2/generated/code/Magento/Catalog/Controller/Adminhtml/Product/Edit/Interceptor.php(23): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->___callPlugins() #24 /var/www/magento2/vendor/magento/framework/App/Action/Action.php(111): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->execute() #25 /var/www/magento2/vendor/magento/module-backend/App/AbstractAction.php(151): Magento\Framework\App\Action\Action->dispatch() #26 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Backend\App\AbstractAction->dispatch() #27 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->___callParent() #28 /var/www/magento2/vendor/magento/module-backend/App/Action/Plugin/Authentication.php(145): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->Magento\Framework\Interception\{closure}() #29 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch() #30 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->Magento\Framework\Interception\{closure}() #31 /var/www/magento2/generated/code/Magento/Catalog/Controller/Adminhtml/Product/Edit/Interceptor.php(32): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->___callPlugins() #32 /var/www/magento2/vendor/magento/framework/App/FrontController.php(245): Magento\Catalog\Controller\Adminhtml\Product\Edit\Interceptor->dispatch() #33 /var/www/magento2/vendor/magento/framework/App/FrontController.php(212): Magento\Framework\App\FrontController->getActionResponse() #34 /var/www/magento2/vendor/magento/framework/App/FrontController.php(147): Magento\Framework\App\FrontController->processRequest() #35 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch() #36 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent() #37 /var/www/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}() #38 /var/www/magento2/generated/code/Magento/Framework/App/FrontController/Interceptor.php(23): Magento\Framework\App\FrontController\Interceptor->___callPlugins() #39 /var/www/magento2/vendor/magento/framework/App/Http.php(116): Magento\Framework\App\FrontController\Interceptor->dispatch() #40 /var/www/magento2/generated/code/Magento/Framework/App/Http/Interceptor.php(23): Magento\Framework\App\Http->launch() #41 /var/www/magento2/vendor/magento/framework/App/Bootstrap.php(264): Magento\Framework\App\Http\Interceptor->launch() #42 /var/www/magento2/pub/index.php(30): Magento\Framework\App\Bootstrap->run() #43 {main}
对应报错文件/var/www/magento2/vendor/magento/framework/View/Element/UiComponent/DataProvider/Sanitizer.php的关键代码:
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Framework\View\Element\UiComponent\DataProvider; use Magento\Framework\Phrase; /** * Sanitizes data received from UI data providers. */ class Sanitizer { // ...其他方法省略... /** * Sanitize a component's metadata. * * Will sanitize full component's metadata as well as metadata of it's child components. * * @param array $meta * @return array */ public function sanitizeComponentMetadata(array $meta): array { if (array_key_exists('arguments', $meta) && is_array($meta['arguments']) && array_key_exists('data', $meta['arguments']) && is_array($meta['arguments']['data']) && array_key_exists('config', $meta['arguments']['data']) && is_array($meta['arguments']['data']['config']) ) { $meta['arguments']['data']['config'] = $this->sanitize($meta['arguments']['data']['config']); } if (array_key_exists('children', $meta) && is_array($meta['children'])) { $meta['children'] = array_map([$this, 'sanitizeComponentMetadata'], $meta['children']); } return $meta; } }
已执行过重新编译、重新索引、清除缓存操作,问题未解决。
解决方案
1. 定位问题根源
错误是因为sanitizeComponentMetadata方法要求传入数组,但实际传入了null。这通常是迁移过程中自定义属性/UI组件的元数据损坏,或者第三方模块的UI组件配置异常导致的。
2. 排查与修复步骤
- 禁用第三方模块排查冲突:临时禁用所有非官方模块,再尝试打开产品页面。如果问题消失,逐个启用模块找到冲突项,检查其UI组件配置文件(
*.xml)是否存在语法错误或无效元数据定义。 - 检查产品属性数据:迁移后的产品属性可能存在格式错误,运行以下SQL排查异常属性:
重点排查SELECT attribute_id, attribute_code, frontend_input, is_user_defined FROM eav_attribute WHERE entity_type_id = 4;frontend_input为空或异常的属性,以及自定义属性的backend_model、frontend_model配置是否兼容Magento 2.4.6。 - 覆盖Sanitizer类处理空值:创建自定义模块,在
etc/di.xml中添加偏好设置:
然后创建覆盖类:<preference for="Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer" type="Vendor\Module\View\Element\UiComponent\DataProvider\Sanitizer" /><?php declare(strict_types=1); namespace Vendor\Module\View\Element\UiComponent\DataProvider; use Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer as OriginalSanitizer; class Sanitizer extends OriginalSanitizer { public function sanitizeComponentMetadata($meta): array { // 处理null值,返回空数组避免类型错误 if (!is_array($meta)) { return []; } return parent::sanitizeComponentMetadata($meta); } } - 重置产品表单UI配置:执行以下命令重置UI配置并刷新缓存:
bin/magento setup:upgrade bin/magento cache:flush
3. 验证修复
完成上述操作后,重新执行编译、索引、清除缓存操作,再次尝试打开产品编辑页面,检查前端产品展示是否恢复正常。
内容的提问来源于stack exchange,提问作者Kael Fox
相关产品推荐
相关产品推荐

