3

I'm seeing the following error on my Drupal 8.4.3 site:

User error: "attributes" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).

It happens when rendering a Paragraph that has a multi-value field in it, which uses the Responsive Image formatter.

The Twig template looks like this:

...
{% for item in items %}
  {% set original_image = item.content['#item'].getValue()['original_url'] %}
  <a href="#" target="_blank" rel="nofollow">
    {{ item }}
  </a>
{% endfor %}
....

The problem is on that middle line {{ item }}. It prints the error message once per item in the "items" array. According to the Twig debug output in the HTML source, the next inner Twig template should be core/themes/stable/templates/field/responsive-image-formatter.html.twig. For fun, I went into that template and deleted every line, leaving an empty file. And the error is still there. So it's happening somewhere between the outer template and the inner template.

When I put a step debugger on line 97, I see a variable $elements with the following structure:

[
'content' => ... render array stuff in here ...,
'attributes' => Drupal\Core\Template\Attribute[ storage => [] ],  // <-- what's this?
'#printed' => false,
'#cache' => ...,
'#attached' => []
]

It seems that the problem is that Drupal wants anything not starting with # to be a valid render array. Which the 'attributes' element isn't. But I can't figure out how that got in there. I don't think any of my custom code could generate something like "'storage' => []". I've been poring over the stack trace for hours and I can't tell where it's coming from.

Anyone know of a contribibuted or core module that could generate this? I would love to file an issue in the Drupal issue queue, but I can't even figure out which module is causing this.

System specs:

  • Drupal 8.4.3
  • Paragraphs 8.x-1.2 (the field in question is inside a Paragraph entity)
  • Multiversion 8.x-1.0-beta7 (in case that matters; it does change entity structure somewhat)
  • Image Lazyloader 8.x-1.0-alpha2 (I've seen this in the stack trace a few times)
  • PHP 7.0.26
  • Ubuntu 16.04

2 Answers 2

16

Yes, it seems like you are not supposed to render item in a field template. Render item.attributes and item.content separately:

<div{{ item.attributes }}>{{ item.content }}</div>

Or the attributes in a <span> if the <div> doesn't work with your layout and you need the attributes:

<span{{ item.attributes }}>{{ item.content }}</span>

BTW storage' => [] is part of the Attribute object any code can store attributes on its way until it reaches your template. So it's a good idea to print the attributes, even if they are now empty, because you don't know which extension you might want to install in the future and debugging will then be some fun until you'll find out that one of the field templates is not fully working.

3
  • 1
    Worked like a charm. Thanks for the quick answer. Wish that error message was a bit more useful...
    – kdechant
    Jan 13, 2018 at 8:22
  • Excellent. For anyone else encountering this issue, it was specifically on a paragraph template. {{ item }} must be rendered as {{ item.content }}. Jan 25, 2018 at 22:35
  • The same ould be the case, if you only wanted to render the first item: {{ items.0 }} will get the error, {{ items.0.content }} fixes it
    – yunzen
    Oct 16, 2019 at 10:57
2

In a view template, I had to do something similar:

{% for row in rows %}
{#  {{ row }} #}
  <div{{ row.attributes }}>{{ row.content }}</div>
{% endfor %}

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.