1

my website has been running for while and the url key for some category have been using for long. but suddenly some category pages (most others are still valid) referenced by url-key.html not working. the backend report show

enter image description here Unable to serialize value. Error: Malformed UTF-8 characters, possibly incorrectly encoded

i tried to delete the url-key and give a new one, but not successful. there is error also.

enter image description here do you have any idea?

2 Answers 2

0

create:

Vendor\Framework\registration.php

    <?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Vendor_Framework',
    __DIR__
);

Vendor\Framework\etc\module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Framework">
        <sequence>
            <module name="Magento_Framework" />
        </sequence>
    </module>
</config>

Vendor\Framework\etc\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <preference for="Magento\Framework\Serialize\Json" type="Magento\Framework\Serialize\Serializer\Json" />
    <preference for="Magento\Framework\Serialize\Serializer\Json" type="Vendor\Framework\Rewrite\Magento\Framework\Serialize\Serializer\Json" />
</config>

Vendor\Framework\Rewrite\Magento\Framework\Serialize\Serializer\Json.php

<?php

namespace Vendor\Framework\Rewrite\Magento\Framework\Serialize\Serializer;

class Json extends \Magento\Framework\Serialize\Serializer\Json
{
    public function utf8ize( $mixed ) {
        if (is_array($mixed)) foreach ($mixed as $key => $value) $mixed[$key] = $this->utf8ize($value);
        elseif (is_string($mixed)) return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
        return $mixed;
    }


    public function serialize($data){
        $result = json_encode( $this->utf8ize( $data ) );
        if (false === $result) {
            throw new \InvalidArgumentException("Unable to serialize value. Error: " . json_last_error_msg());
        }
        return $result;
    }

    
    public function unserialize($string)
    {
        $result = json_decode($string, true);
        if (json_last_error() !== JSON_ERROR_NONE)
        {
            throw new \InvalidArgumentException("Unable to unserialize value. Error: " . json_last_error_msg());
        }
        return $result;
    }
}
0

You have 2 issues:

Issue 1. "Unable to serialize value. Error: Malformed UTF-8 characters, possibly incorrectly encoded", there are 2 cases related to this error message:

  • Case 1 (your case), only some pages have this error, so your data caused this error. To resolve that, take the following step to override vendor/magento/framework/Serialize/Serializer/Json.php:

Step 1: Create registration.php:

File path: app/code/Vendor/Module/registration.php

<?php

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Vendor_Module', __DIR__);

Step 2: Create module.xml:

File path: app/code/Vendor/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Module">
        <sequence>
            <module name="Magento_Framework"/>
        </sequence>
    </module>
</config>

Step 3: Create the di.xml:

File path: app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Framework\Serialize\Serializer\Json" type="Vendor\Module\Serialize\Serializer\Json" />
</config>

Step 4: Create Json.php:

File path: app/code/Vendor/Module/Serialize/Serializer/Json.php

<?php
namespace Vendor\Module\Serialize\Serializer;

class Json extends \Magento\Framework\Serialize\Serializer\Json
{
    public function serialize($data) {
        $result = json_encode($this->utf8ize($data));
        if (false === $result) {
            throw new \InvalidArgumentException("Unable to serialize value. Error: " . json_last_error_msg());
        }
        return $result;
    }

    public function unserialize($string)
    {
        if ($string === null) {
            throw new \InvalidArgumentException(
                sprintf('Invalid parameter: string must be a string type, null given.')
            );
        }

        $result = json_decode($string, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            if (false !== @unserialize($string)) {
                return unserialize($string);
            }
            throw new \InvalidArgumentException('Unable to unserialize value.');
        }
        return $result;
    }

    public function utf8ize($mixed) {
        if (is_array($mixed)) foreach ($mixed as $key => $value) $mixed[$key] = $this->utf8ize($value);
        elseif (is_string($mixed)) return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
        return $mixed;
    }
}

Step 6: Run the setup:upgrade command to make your new module active, and then compile code, deploy static content:

bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f

Done.

  • Case 2: If your error trace said the error was related to Magento Recaptcha module, you faced the issue with MSP_ReCaptcha module (magento core module), check the github issue for more details: https://github.com/magento/magento2/issues/30486

This is due to the MSP_ReCaptcha module storing the public key in plain text (type="text"), but the Magento recaptcha module stores it encrypted (type="obscure"). The migration however just copies the plain text value over, so when it is "decrypted", the resulting value is invalid.

To fix this get the msp_securitysuite_recaptcha/general/public_key value from the core_config_data (or your Google ReCaptcha admin page) and run the following commands:

php bin/magento config:set recaptcha_frontend/type_invisible/public_key YOURPUBLICKEY
php bin/magento config:set recaptcha_backend/type_invisible/public_key YOURPUBLICKEY

The command correctly encrypts the value when adding it to the database.

Issue 2. URL rewrite issue: try to use Elgentos Regenerate Catalog URLs module to regenerate URL rewrites: https://github.com/elgentos/magento2-regenerate-catalog-urls

In case you still have issues, feel free to let me know.

4
  • For case 1, I follow your code to build the module, both setup:upgrade and di:compile finished without issue. but when setup:static-content:deploy, it complains "Class Secuware\Serializer\Serialize\Serializer\Json does not exist", I called my module Secuware_Serializer. my file is in app/code/Secuware/Serializer/Serialize/Serializer/Json.php. am I wrong? Commented Oct 31, 2022 at 9:43
  • Please change the file paths for Vendor/Module/etc/di.xml and Vendor/Module/Serialize/Serializer/Json.php to follow the latest update in my answer.
    – Tu Van
    Commented Oct 31, 2022 at 10:33
  • maybe i misunderstood, but i see the paths have been the same as yours. app\code\Secuware\Serializer\Serialize\Serializer\Json.php and app\code\Secuware\Serializer\etc\di.xml, i replace Vendor with Secuware and Module with Serializer. am i doing wrong? Commented Oct 31, 2022 at 11:33
  • It is correct, please double-check file paths and namespace in Json class, di.xml file as my answer. I've tested it, and it works.
    – Tu Van
    Commented Nov 2, 2022 at 6:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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