getgrav/grav · error · UnexpectedValueException

{% {$this->tagName} with x %}: x is not an array

Error message

{% {$this->tagName} with x %}: x is not an array

What it means

The {% style %} tag's compile() emits the same guarded assignment as script/link: the `with <expr>` clause becomes $attributes and the compiled template throws UnexpectedValueException unless it is an array (default [] when absent). The clause holds link/style HTML attributes and must be a Twig mapping or array-valued expression; scalar or null values abort rendering.

Source

Thrown at system/src/Grav/Common/Twig/Node/TwigNodeStyle.php:63

    /**
     * Compiles the node to PHP.
     *
     * @param Compiler $compiler A Twig Compiler instance
     * @return void
     * @throws LogicException
     */
    public function compile(Compiler $compiler): void
    {
        $compiler->addDebugInfo($this);

        if ($this->hasNode('attributes')) {
            $compiler
                ->write('$attributes = ')
                ->subcompile($this->getNode('attributes'))
                ->raw(';' . PHP_EOL)
                ->write('if (!is_array($attributes)) {' . PHP_EOL)
                ->indent()
                ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL)
                ->outdent()
                ->write('}' . PHP_EOL);
        } else {
            $compiler->write('$attributes = [];' . PHP_EOL);
        }

        if ($this->hasNode('group')) {
            $compiler
                ->write('$group = ')
                ->subcompile($this->getNode('group'))
                ->raw(';' . PHP_EOL)
                ->write('if (!is_string($group)) {' . PHP_EOL)
                ->indent()
                ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL)
                ->outdent()
                ->write('}' . PHP_EOL);
        } else {
            $compiler->write('$group = \'head\';' . PHP_EOL);

View on GitHub (pinned to 6040efed04)

Solutions

  1. Use a mapping literal: {% style 'theme.css' with { media: 'print' } %}
  2. Ensure the variable is an array: {% set attrs = {media: 'print'} %} then {% style 'theme.css' with attrs %}
  3. Default null variables: {% set attrs = attrs ?? {} %}

Example fix

{% set media = 'print' %}
{# before: scalar passed to with #}
{% style 'theme.css' with media %}

{# after: mapping literal #}
{% style 'theme.css' with { media: 'print' } %}
Defensive patterns

Strategy: validation

Validate before calling

{# in Twig, guard the variable before the tag #}
{% set attrs = attrs is defined and attrs is iterable ? attrs : {} %}
{% style 'theme.css' with attrs %}

Try / catch

try { echo $twig->render($template, $data); } catch (UnexpectedValueException $e) { log_template_error($e); }

Prevention

When it happens

Trigger: {% style 'theme.css' with media %} where media is a string variable; {% style 'a.css' with 'media=print' %} (attribute string instead of mapping); an attributes variable left null by surrounding logic.

Common situations: Handwriting style tags without braces on the attribute mapping; variables expected to be hashes but containing strings after refactors; copied examples that use shorthand syntax.

Related errors


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/6bce39f87a35a82b. Report an issue: GitHub.