Magento 2.2.1 Unable to serialize value

As I can see this error comes from the method:

/**
 * Saving data cache
 *
 * @return $this
 */
protected function _saveCache()
{
    $this->_cache->save($this->getSerializer()->serialize($this->getData()), $this->getCacheId(true), [], false);
    return $this;
}

and serializer which is not found comes from the method:

/**
 * Get serializer
 *
 * @return \Magento\Framework\Serialize\SerializerInterface
 * @deprecated 100.2.0
 */
private function getSerializer()
{
    if ($this->serializer === null) {
        $this->serializer = \Magento\Framework\App\ObjectManager::getInstance()
            ->get(Serialize\SerializerInterface::class);
    }
    return $this->serializer;
}

The preference for the SerializerInterface was added since 2.2.x version of the Magento, and declared in the app/etc/di.xml:

<preference for="Magento\Framework\Serialize\SerializerInterface" type="Magento\Framework\Serialize\Serializer\Json" />

So I think your cache is old or the preference for the SerializerInterface is not working. Try to debug this issue by calling the Magento\Framework\Serialize\SerializerInterface (using dependency injection) somwhere in code, and check which class returned by di:

public function __construct(\Magento\Framework\Serialize\SerializerInterface $serializer) 
{ 
    echo get_class($serializer);
}

If it returns not an instance of the Magento\Framework\Serialize\Serializer\Json class returned - try to search this overwritten preference in the project and remove it.

If you are working on the remote server - firstly check the app/etc/di.xml file on the server directly.

Another way you can temporarly modify the core Json serializer and check which error returned:

Open the magento/framework/Serialize/Serializer/Json.php and change this method from:

/**
 * {@inheritDoc}
 * @since 100.2.0
 */
public function serialize($data)
{
    $result = json_encode($data);
    if (false === $result) {
        throw new \InvalidArgumentException('Unable to serialize value.');
    }
    return $result;
}

to:

/**
 * {@inheritDoc}
 * @since 100.2.0
 */
public function serialize($data)
{
    $result = json_encode($data);
    if (false === $result) {
        switch (json_last_error()) {
            case JSON_ERROR_NONE:
                $error = ' - No errors';
                break;
            case JSON_ERROR_DEPTH:
                $error = ' - Maximum stack depth exceeded';
                break;
            case JSON_ERROR_STATE_MISMATCH:
                $error = ' - Underflow or the modes mismatch';
                break;
            case JSON_ERROR_CTRL_CHAR:
                $error = ' - Unexpected control character found';
                break;
            case JSON_ERROR_SYNTAX:
                $error = ' - Syntax error, malformed JSON';
                break;
            case JSON_ERROR_UTF8:
                $error = ' - Malformed UTF-8 characters, possibly incorrectly encoded';
                break;
            default:
                $error = ' - Unknown error';
                break;
        }
        throw new \InvalidArgumentException('Unable to serialize value. Error: ' . $error);
    }

    return $result;
}

Then you can see after the exception message a json error. May be your data is broken. keep in mind that all the old data should be unserialized and serialized using json in the setup upgrade scripts during magento update.

PS: do not forget to revert back the core files after debugging complete! The better way is use xDebug for that purpose.


i have the same behaviour with an template. I copied the code for the error to my serializer to get my problem.

As soon as i switch to de_DE and regenerate my static code via

sudo php bin/magento setup:static-content:deploy de_DE --jobs=0 -f

it throws "Malformed UTF-8 characters, possibly incorrectly encoded".

So i looked up the files i changed in the template folder (i.e. code/Mytheme/Bannerslider/i18n/de_DE.csv) and downloaded them via WinSCP. Notepad++ showed "Ansii Encoding" - hard it i used "magento i18n:collect-phrases" for the translation file to create.

magento2dev # encguess app/code/MyTheme/Bannerslider/i18n/de_DE.csv

app/code/MyTheme/Bannerslider/i18n/de_DE.csv US-ASCII

magento2dev # locale
LANG=de_DE.UTF-8
......

So i changed the files manually in Notepad++, uploaded them, deployed the static content and reset all permissions - en voila it works.

So, the bug could be in your i18n csv file.


In my case the cause to a UTF8 Encoding problem, was non-multibyte safe shortening of product names:

$productName = strlen($productName) > 60 ? substr($productName,0,60)."..." : 
      $productName;

So a

012345678901234567890123456789012345678901234567890123456 Außengewinde 

became

012345678901234567890123456789012345678901234567890123456 Au�...