Summary
When a Code field is converted to a Plain Text field via the Craft CP field settings, the existing database values (stored as ['value' => '...', 'language' => '...'] arrays) are passed directly to craft\fields\PlainText::_normalizeValueInternal(). That method passes the value to StringHelper::shortcodesToEmoji(), which has a string type hint and throws a TypeError.
Steps to Reproduce
- Create a field previously typed as Code (nystudio107/craft-code-field) with saved entries.
- Change the field type to Plain Text in the Craft CP.
- Open any entry that has a value saved for that field.
Expected Behaviour
The entry editor opens without error. The stored array should be migrated to its value string, or handled gracefully.
Actual Behaviour
TypeError: craft\helpers\StringHelper::shortcodesToEmoji(): Argument #1 ($str) must be of type string, array given,
called in /var/www/html/vendor/craftcms/cms/src/fields/PlainText.php on line 183
The raw DB value being passed to PlainText is:
['value' => '{{ childEntry.keywordFeatureName...', 'language' => 'twig']
Stack Trace (key frames)
StringHelper::shortcodesToEmoji(Array) StringHelper.php:2689
PlainText::_normalizeValueInternal(Array, Entry, false) PlainText.php:183
PlainText::normalizeValue(Array, Entry) PlainText.php:168
Element::normalizeFieldValue('featureOverviewSubheadline') Element.php:6850
CustomField::inputHtml(Entry, false) CustomField.php:815
Root Cause
The Code field serialises its data as a {value, language} object. When the field type changes to Plain Text, Craft reads the raw DB value and passes it to PlainText::normalizeValue() with no conversion. PlainText does not guard against receiving an array.
A fix in the plugin could override normalizeValue() to detect the legacy array format and return only the value string, ensuring a clean field-type migration.
Environment
- Craft CMS 5.x
- nystudio107/craft-code-field (latest)
- PHP 8.x
Summary
When a Code field is converted to a Plain Text field via the Craft CP field settings, the existing database values (stored as
['value' => '...', 'language' => '...']arrays) are passed directly tocraft\fields\PlainText::_normalizeValueInternal(). That method passes the value toStringHelper::shortcodesToEmoji(), which has astringtype hint and throws aTypeError.Steps to Reproduce
Expected Behaviour
The entry editor opens without error. The stored array should be migrated to its
valuestring, or handled gracefully.Actual Behaviour
The raw DB value being passed to PlainText is:
Stack Trace (key frames)
Root Cause
The Code field serialises its data as a
{value, language}object. When the field type changes to Plain Text, Craft reads the raw DB value and passes it toPlainText::normalizeValue()with no conversion.PlainTextdoes not guard against receiving an array.A fix in the plugin could override
normalizeValue()to detect the legacy array format and return only thevaluestring, ensuring a clean field-type migration.Environment