After upgrading from Craft 3 to Craft 4, the backend is accessible but the frontend displays the error:

PHP Warning – yii\base\ErrorException Array to string conversion

And points to many files:

Such as:

in /app/vendor/craftcms/cms/src/helpers/Db.phpat line 604
595596597598599600601602603604605606607608609610611612613                    $condition[] = [$column => $val];
                if (
                    static::isNumericColumnType($columnType) &&
                    $val !== ':empty:' &&
                ) {
                    throw new InvalidArgumentException("Invalid numeric value: $val");
            if ($val === ':empty:') {
                // If this is a textual column type, also check for empty strings
                if (
                    ($columnType === null && $isMysql) ||
                    ($columnType !== null && static::isTextualColumnType($columnType))
                ) {


in /app/templates/_components/header.twig at line 25– craft\helpers\Template::attribute(craft\web\twig\Environment, Twig\Source, craft\elements\db\CategoryQuery, 'all', ...)
19202122232425262728293031{% set solutionsLevel2 = null %}
{% set pageType = entry.type ??? null %}
{# Get all descendants of level 2 #}
{% if mainMenu %}
{{ dump(mainMenu) }}
    {% set solutions = craft.categories().group('solutions').id([mainMenu.ids()]).all() ??? null %}
{% else %}
    {% set solutions = craft.categories().group('solutions').all() ??? null %}
{% endif %}
{% if solutions %}
    {% set solutionsLevel2 = solutions|filter(v => v.level == 2) ??? null %}


 in /app/templates/_base/base-web-layout.twig at line 101– Twig\Template::display(['entry' => craft\elements\Entry, 'variables' => ['entry' => craft\elements\Entry], 'craft' => craft\web\twig\variables\CraftVariable, 'currentSite' => craft\models\Site, ...])
            {% if cookieBannerSnippet %}
                {{ cookieBannerSnippet|raw }}
            {% endif %}
        {% endblock bodyTag %}
        {% include "_components/header.twig" %}
        {# -- Page content that should be included in the <body> -- #}
        {% block bodyContent %}{% endblock bodyContent %}
        {# do not cache footer because of form #}
        {% include "_components/footer.twig" %}


 in /app/templates/_base/base-web-layout.twig at line 1– Twig\Template::displayBlock('htmlPage', ['entry' => craft\elements\Entry, 'variables' => ['entry' => craft\elements\Entry], 'craft' => craft\web\twig\variables\CraftVariable, 'currentSite' => craft\models\Site, ...], ['htmlPage' => [__TwigTemplate_e46420d563df21c4bfb0ea5103d757fa, 'block_htmlPage'], 'htmlTag' => [__TwigTemplate_e46420d563df21c4bfb0ea5103d757fa, 'block_htmlTag'], 'headTag' => [__TwigTemplate_e46420d563df21c4bfb0ea5103d757fa, 'block_headTag'], 'headContent' => [__TwigTemplate_e46420d563df21c4bfb0ea5103d757fa, 'block_headContent'], ...])
1234567{%- block htmlPage -%}
<!DOCTYPE html>
{% block htmlTag %}
    <html lang="{{ craft.app.language |slice(0,2) }}" class="h-full">
    {% endblock htmlTag %}
    {% block headTag %}

There are more examples.

I am not sure if these are all related.

I have tried to delete /storage/runtime/compiled_templates

I have also tried nuking the /vendor folder and running composer install again.

None of this has helped unfortunately.

1 Answer 1


So to clarify what you're seeing with the error message and all the files - this is what is called a stack trace. So the file/code causing the error is always (or at least almost always) the top most file in the list, and then the succeeding files just tell you why and where the preceeding file got called. In other words, the screen is telling you "Here's the file (X) causing this error, and here (Y) is where that X file is being referenced, and here (Z) is where the Y file is being referenced", and so on and so forth. So you shouldn't need to pay too much attention to anything below that first file in the list, especially for an error message coming from your Twig code.

The offending line should be highlighted on your screen (I can't tell from the copy paste which one it is), but that should give you a great starting point in figuring out why the error is happening. An "Array to string conversion" error means somewhere you're passing an array and it's expecting a string.

If I had to guess, I would probably say it's this bit of code: .id([mainMenu.ids()]) - I think that should instead be .id(mainMenu.ids()). The ids() method returns an array to begin with, so by surrounding it with your own square brackets you're making it a multidimensional array (e.g. .id([[1, 2, 3]])), and the .id() parameter is probably looking for a single integer or a one-dimensional array (e.g. .id([1, 2, 3])).

  • Thank you, it turned out to be multiple issues. The main one being that mainMenu was indeed empty on certain pages. I was able to fix it by changing {% if mainMenu %} to {% if mainMenu is not empty %}
    – BrokenCode
    Mar 23 at 7:22

Your Answer

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

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