Problem/Motivation
Hello team, I encountered this error after upgrading from beta1 -> beta2
Drupal\Core\Render\Component\Exception\InvalidComponentException: [attributes] String value found, but an object is required in Drupal\Core\Theme\Component\ComponentValidator->validateProps() (line 203 of core/lib/Drupal/Core/Theme/Component/ComponentValidator.php).
Drupal\Core\Template\ComponentsTwigExtension->doValidateProps(Array, 'careerforce_skin:sdc-button') (Line: 109)
Drupal\Core\Template\ComponentsTwigExtension->validateProps(Array, 'careerforce_skin:sdc-button') (Line: 43)
__TwigTemplate_2e7947f54dec3d43cd615960f13e0186->doDisplay(Array, Array) (Line: 360)
Twig\Template->yield(Array, Array) (Line: 174)
__TwigTemplate_2963595ff175389c52b90bc1b95d0f52___1421564442->doDisplay(Array, Array) (Line: 360)
Twig\Template->yield(Array) (Line: 56)
__TwigTemplate_2963595ff175389c52b90bc1b95d0f52->doDisplay(Array, Array) (Line: 360)
Twig\Template->yield(Array) (Line: 335)
Twig\Template->render(Array) (Line: 38)
Twig\TemplateWrapper->render(Array) (Line: 33)
twig_render_template('themes/custom/careerforce_skin/templates/form/input--submit.html.twig', Array) (Line: 348)
I created a SDC button with this YML
name: Careerforce_Skin - SDC Button
description: A button draws attention to important actions with a large selectable surface.
variants:
default:
title: Default
secondary:
title: Secondary
inverse:
title: Inverse
slots:
children:
title: Children
description: 'The button children.'
props:
type: object
properties:
text:
title: Text
type: string
default: Read more
url:
title: URL
type: string
description: 'The button URL. Optional.'
default: https://www.govwebworks.com/
$ref: 'ui-patterns://url'
This is my input__submit preprocess
function careerforce_skin_preprocess_input__submit(&$variables) {
if (isset($variables['element']['#is_secondary_button'])) {
$variables['is_secondary_button'] = $variables['element']['#is_secondary_button'];
}
if (isset($variables['element']['#is_inverse_button'])) {
$variables['is_inverse_button'] = $variables['element']['#is_inverse_button'];
}
}
And the input--submit.html.twig
{% set variant = 'default' %}
{% if is_secondary_button %}
{% set variant = 'secondary' %}
{% elseif is_inverse_button %}
{% set variant = 'inverse' %}
{% endif %}
{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} %}
{% block children %}
{{ children }}
{% endblock %}
{% endembed %}
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | Screenshot 2024-10-12 at 5.18.05 PM.png | 120.83 KB | smustgrave |
| #9 | Screenshot from 2024-09-20 22-09-23.png | 220.27 KB | sea2709 |
| #9 | Screenshot from 2024-09-20 22-07-51.png | 216.22 KB | sea2709 |
Issue fork ui_patterns-3474822
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
pdureau commentedComment #3
pdureau commentedComment #5
christian.wiedemann commentedThis is a core issue. The component is rendered inside a form field which is not mapped by ui patterns.
Or I am wrong?
Comment #6
christian.wiedemann commentedComment #7
pdureau commentedIndeed, it doesn't look like an UI Patterns issue, because this snippet uses stuff we are trying to avoid with UI Patterns 2:
|raw()filterSo this may be a "support request".
What are the
careerforce_skin:sdc-buttoncomponent definition & template?Comment #8
pdureau commentedComment #9
sea2709 commentedThanks for your response. Not sure if my implementation is correct. The idea is I would like the submit buttons are rendered by using a button SDC component, so that's why I created a twig template file input__submit.html.twig and rendered the button component here.
This piece of code went well on UI Patterns 2.0.0-beta1, I only encounter the invalid component exception after I upgraded to beta2.
I did some debugging and this is what I found
On beta-1, during the component validation checking at

Drupal\Core\Theme\Component\ComponentValidator, thepropsvariable has 2 propertiesvariantandtextOn beta-2, during the component validation checking at

Drupal\Core\Theme\Component\ComponentValidator, thepropsvariable has 3 propertiesvariant,textandattributesI think
attributesshould be an object or an array, not a string. I guess maybe somewhere on UI Patterns 2-beta2, the attributes prop is converted to a stringComment #10
pdureau commentedYou are getting an error which was "fixed" by #3470231: [2.0.0-beta2] Attributes normalization
The root cause is triggered SDC's ComponentValidator::validateProps() which is calling a dependency method which is executing json_encode() which is casting the attribute object into a string.
So, this issue is fixed with a SDC render element alteration by UI Patterns 2, but you are still getting it. Why?
Maybe because you are using
{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} %}which is not triggering the SDC render element.In this order:
1. Because you are not passing
attributes, you can start by adding theonlykeyword. Non tested proposal:{% embed 'careerforce_skin:sdc-button' with { text: attributes.value|raw, variant: variant} only %}. See: https://twig.symfony.com/doc/3.x/tags/embed.html2. If you still have the issue or if you want to pass attributes to the component, make it explicit and convert to array. Non tested proposal:
{% embed 'careerforce_skin:sdc-button' with { attributes: attributes.toArray(), text: attributes.value|raw, variant: variant} only %}3. If you still have the issue, replace Twig
embedandblockby acomponent()function. Non tested proposal:Is it helping?
Comment #11
sea2709 commentedThanks @pdureau,
It's helping! This code works for my case on beta2, with and without only!
{% embed 'careerforce_skin:sdc-button' with { attributes: attributes.toArray(), text: attributes.value|raw, variant: variant} only %}Thank you for your help! I guess I need some time to digest your response, I'm a little bit exhausted at this moment, but I'm glad that it works :-)
Comment #12
smustgrave commentedSo I'm reopening this one as I'm noticing this when using patterns from a view
Using ui_suite_uswds 4.0.x branch
ui_patterns latest beta.
For ease I duplicated the admin content view and removed the admin part from the new url so it uses the front end theme.
ui_pattern-devel must be uninstalled.
I now get a fatal error
The error I believe is because the #value key is an attribute object now.
Comment #13
pdureau commentedLet's target the next beta
However, I am still not reproducing the issue.
commit 544dfaa4704bf2b3dca5faeb794277777264dee1 (HEAD -> 4.0.x, origin/HEAD, origin/4.0.x)duplicate_of_contentview with/contentpage displayui_pattern_develis not installedOther information about my environment:
Comment #14
smustgrave commentedWill try and gather additional steps but it's reproducible for me 100% of the time.
Though I believe the bug lies with core or views
Comment #15
smustgrave commentedFresh install
Drupal 11.0.5
Drush 13
Php 8.3
Ui suite uswds 4.0.x
Ui patterns beta3
Install all needed files
Leave ui patterns devel off
Enable theme, using CDN to pull USWDS library in
Go to admin/structure/views/view/content
Duplicate the page
Change URL from admin/content/node to content/node
Need to have at least 1 piece of content
Go to the page and see the errors.
Comment #16
just_like_good_vibeshello,
i am debugging your problem,
first thing i found, in file
form-element-label.html.twig,the title is provoking a bug on my instance. if you replace "title" by "title|render", it works.
Second thing i found, in file
views-view-table.html.twig,line 140
the attributes injected are containing (at twig render time), an invalida value at key "headers".
add
.removeAttribute('headers')at line 142, after.addClass(column_classes)and it will work.Comment #17
sea2709 commentedNot sure if it's helpful. In my case, I noticed that the component SDC-button I created hasn't been processed by the function "processAttributesProp" in ComponentElementAlter.php to convert the attributes object type
'\Drupal\Core\Template\Attribute'into an array, while the other components have. I only see only button component encounters this issue. In my case, I don't think it's because of views, will share more information when I figure out something!Comment #18
pdureau commentedLet's discuss this after beta4.
Comment #19
pdureau commentedWe will:
LinksPropType::normalizeAttributes()inAttributePropType::normalize()AttributePropType::normalize()fromLinksPropType::normalize()AttributePropType::normalize()some logic about attribute value being list and not associative arrayAttributePropType::normalize()some logic about renderable interface & stringable interface inspired bySlotPropType::convertObject()(if possible, implement this inStringPropType:normalize()and call it)Comment #21
pdureau commentedSo:
DONE in commit b32351950f6:
LinksPropType::normalizeAttributes()inAttributePropType::normalize()>>AttributePropType::normalize()fromLinksPropType::normalize()DONE in commit 4ed020f26eda:
AttributePropType::normalize()some logic about attribute value being list and not associative arrayAttributePropType::normalize()some logic about renderable interface & stringable interface inspired bySlotPropType::convertObject()So, I hope we addressing the 2 issues met by Steven from this ticket:
(JSON encoding is only for extreme use case, most iof the normalization do'nt rely on this workaround)
About Dang Tran feedback:
Interesting, maybe the logic of ComponentElementAlter::processAttributesProp() can also move to
AttributePropType::normalize().Anyway, I don't know what is happening with those
{% embed %}thingy. Maybe we will need to revamp this hacky part of the SDC API next year, moving some logic from the TwigNodeVisitor to the Render Element.Comment #22
pdureau commentedComment #23
pdureau commentedComment #24
pdureau commentedComment #25
pdureau commentedComment #26
just_like_good_vibessuper nice job ! i like the treatment attribute is receiving, because we know it will receives a lot of weird data over time,
mainly calls from twig with variables having values not trivial.
i just have a few remarks to help finish the attribute normalization/sanitization.
when you normalize a list of values in
normalizeList, only the case of an array is covered.i would add maybe two cases :
- important : a is_object test inside this function to call
normalizeObject- less important : when the value inside a list is an array, imagine this is render array. the caller intuitively would like it to be rendered. this may never happens :) why not try to trigger a rendering ?
sometimes
json_encodemay produce unexpected results (memory error or ?), for example if there are objects inside the values we are trying to json_encode. This is maybe too much good attention and intentions to the persons which are adding bad values inside attributes.Why censuring the code to call "render" inside the
normalizeMappingfunction ?Comment #27
just_like_good_vibesComment #28
pdureau commentedBecause I don't know how to test it in
AttributesPropTypeNormalizationTest:)Yes, I am nice guy here :) I add a depth limit?
Great idea.
So, related to my issue with
AttributesPropTypeNormalizationTest. I don't know how to mock a service.Comment #29
sea2709 commentedLooks like the error is still presented on my local. I'll have sometime tomorrow, I'll dig into it!
Comment #30
pdureau commented✅ Depth limit added.
✅ Test added.
Because I don't know how to test it in
AttributesPropTypeNormalizationTest:)Comment #31
sea2709 commentedI spent some time to debug the issue, and was able to reproduce this bug on a fresh D11 install.
Drupal 11
UI Patterns 2.0.x-dev
Uninstall UI Patterns Devel
UI Suite DaisyUI 4.0.0-alpha2
In order to reproduce the bug, I updated the template file
web/themes/contrib/ui_suite_daisyui/templates/menu/menu--account.html.twigasI see that when I render a component in a twig template file, that component doesn't go through the #pre_render process, so attributes prop isn't processed. As a result, the component validation is failed since the attribute prop is a string, but in the schema, attribute prop is an object with the prop type as
ui-patterns://attributesComment #32
pdureau commentedComment #33
smustgrave commentedSo I switch to this branch on 4.0.x branch of USWDS same scenario in #15 and no fatal error!
Comment #35
just_like_good_vibesComment #36
sea2709 commentedLooks like if I use include function in twig file, I still run into a fatal error. I saw your comment on https://www.drupal.org/project/ui_patterns/issues/3481860 about using component function instead of include and embed twig function?
Comment #37
pdureau commentedTwig's
include&embedare not currently a good way to embed components, because they don't trigger the SDC render element. Passing through the render element is an important par of the rendering pipeline.So, we have 2 possibilities:
component(string $component_id, array $slots = [], array $props = [])functioninclude&embedtrigger the render element. We will first experiment this solution in UI Patterns 2.x ( #3449653: [2.0.0-beta5] Replace component() function by native include() function ) and we plan to move the fix to Core: #3484580: Trigger SDC render element when using Twig include or embedComment #38
sea2709 commentedThanks @pdureau for the updates.
Look forward to errors free when using functions from SDC core! In the meantime, I will use component function :-)
Comment #39
pdureau commented