AssertionError in CoreBugFixTextItemBaseDefaultValueTrait::setValue() - getName() returns int for list items, not string
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3563317. --> Reported by: [jurriaanroelofs](https://www.drupal.org/user/52638) Related to !482 >>> <h2></h2> <h3 id="overview">Overview</h3> <p>The <code>CoreBugFixTextItemBaseDefaultValueTrait::setValue()</code> method contains an incorrect assertion that causes a fatal error when DXPR Builder sets values on text fields programmatically.</p> <p>On line 46, the assertion <code>\assert(\is_string($name))</code> fails because <code>TypedDataInterface::getName()</code> can return <code>string|int|null</code> according to Drupal core's interface definition. For field items in a list (like text field deltas), it returns an integer (0, 1, 2...), not a string.</p> <p>From <code>core/lib/Drupal/Core/TypedData/TypedDataInterface.php</code> lines 110-115:</p> <div class="codeblock"> <pre><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br>&nbsp; </span><span style="color: #FF8000">/**<br>&nbsp;&nbsp; * @return string|int|null<br>&nbsp;&nbsp; *&nbsp;&nbsp; If the data is a property of some complex data, the name of the property.<br>&nbsp;&nbsp; *&nbsp;&nbsp; If the data is an item of a list, the name is the numeric position of the<br>&nbsp;&nbsp; *&nbsp;&nbsp; item in the list, starting with 0. Otherwise, NULL is returned.<br>&nbsp;&nbsp; */<br>&nbsp; </span><span style="color: #007700">public function </span><span style="color: #0000BB">getName</span><span style="color: #007700">();<br>&nbsp; <br></span><span style="color: #0000BB">?&gt;</span></span></pre></div> <h4>Steps to reproduce</h4> <ol> <li>Install the Canvas module</li> <li>Install the DXPR Builder module and DXPR Builder Drag and Drop Page submodule</li> <li>Go to <code>/node/add/drag_and_drop_page</code></li> <li>Save the node</li> </ol> <h4>Error message</h4> <pre> The website encountered an unexpected error. Try again later. AssertionError: assert(\is_string($name)) in assert() (line 46 of modules/contrib/canvas/src/Plugin/Field/FieldTypeOverride/CoreBugFixTextItemBaseDefaultValueTrait.php). Drupal\canvas\Plugin\Field\FieldTypeOverride\TextWithSummaryItemOverride-&gt;setValue(Array) (Line: 127) Drupal\Core\TypedData\Plugin\DataType\ItemList-&gt;set(0, '&nbsp;') (Line: 766) Drupal\dxpr_builder\Service\DxprBuilderService-&gt;setEmptyStringToDxprFieldsOnEntity(Object) (Line: 23) Drupal\dxpr_builder\Entity\Node-&gt;preSave(Object) (Line: 529) Drupal\Core\Entity\EntityStorageBase-&gt;doPreSave(Object) (Line: 767) Drupal\Core\Entity\ContentEntityStorageBase-&gt;doPreSave(Object) (Line: 484) </pre><h3 id="proposed-resolution">Proposed resolution</h3> <p>Change line 46 in <code>CoreBugFixTextItemBaseDefaultValueTrait.php</code> from:</p> <div class="codeblock"> <pre><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br>&nbsp; </span><span style="color: #007700">\</span><span style="color: #0000BB">assert</span><span style="color: #007700">(\</span><span style="color: #0000BB">is_string</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">));<br>&nbsp; <br></span><span style="color: #0000BB">?&gt;</span></span></pre></div> <p>To allow string or int (matching the interface):</p> <div class="codeblock"> <pre><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br>&nbsp; </span><span style="color: #007700">\</span><span style="color: #0000BB">assert</span><span style="color: #007700">(\</span><span style="color: #0000BB">is_string</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">) || \</span><span style="color: #0000BB">is_int</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">));<br>&nbsp; <br></span><span style="color: #0000BB">?&gt;</span></span></pre></div> <p>Note: Drupal core's <code>FieldItemBase::setValue()</code> handles this correctly by passing <code>$notify = TRUE</code> to the parent, which then calls <code>onChange()</code> with proper handling. The Canvas override manually calls <code>onChange($name)</code> after passing <code>FALSE</code> to parent, but doesn't account for the fact that <code>$name</code> can be an integer for list items.</p> <h3 id="ui-changes">User interface changes</h3> <p>None</p>
issue