Error handling for action buttons that have limit validation errors in place
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3605640. -->
Reported by: [scott_euser](https://www.drupal.org/user/3267594)
Related to !31 !28
>>>
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>Opening the AI Auto-reference "Suggest from existing terms (Form)" modal on a node with an <code>options_select</code> entity reference field crashes with two bugs:</p>
<ul>
<li><strong>TypeError</strong> in <code>WidgetBase::massageFormValues()</code>: receives a string (the raw entity ID, e.g. <code>"453"</code>) instead of an array. <code>options_select</code> has <code>multiple_values: TRUE</code>, so its widget element's <code>#parents</code> is set to <code>['field_name']</code> directly — no <code>['widget']</code> subkey — meaning the raw POST value is a scalar. Because <code>FieldWidgetFormActionBase::actionButton()</code> sets <code>#limit_validation_errors = []</code>, <code>OptionsWidgetBase::validateElement()</code> never runs to convert the scalar to the expected array structure. When <code>openModalCallback()</code> calls <code>buildEntity()</code>, <code>extractFormValues()</code> passes the raw scalar to <code>massageFormValues(array $values, ...)</code></li>
<li><strong>Null entity type manager</strong>: <code>$entity_type_manager</code> and <code>$entity_display_repository</code> constructor parameters are not declared <code>protected</code>, so PHP constructor promotion never fires. They are passed as extra args to <code>parent::__construct()</code> (which accepts only 7 parameters and silently ignores extras), leaving <code>$this->entityTypeManager</code> and <code>$this->entityDisplayRepository</code> unset. <code>buildModalForm()</code> then crashes with "Call to a member function getStorage() on null".</li>
</ul>
<h4 id="summary-steps-reproduce">Steps to reproduce</h4>
<ul>
<li>Configure an entity reference field on a node type to use the <code>options_select</code> widget</li>
<li>Enable the "Suggest from existing terms (Form)" field widget action on that field</li>
<li>Edit an existing node where the field already has a value selected</li>
<li>Click the AI suggestion action button</li>
</ul>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>In <code>AiAutoReferenceFormSuggestion</code>:</p>
<ul>
<li>Override <code>buildEntity()</code> to catch <code>\Throwable</code> and fall back to <code>$form_object->getEntity()</code> when unvalidated form state causes <code>massageFormValues()</code> to receive a scalar. The fallback (saved entity) is sufficient for <code>buildModalForm()</code>, which only needs entity type/bundle/field-definition context.</li>
<li>Declare <code>$entityTypeManager</code> and <code>$entityDisplayRepository</code> as explicit class properties and assign them in the constructor body. Remove the extra args from the <code>parent::__construct()</code> call.</li>
</ul>
<h3 id="summary-remaining-tasks">Remaining tasks</h3>
<ul>
<li>Review whether the <code>buildEntity()</code> fallback should also cover other widget types with <code>multiple_values: TRUE</code> that exhibit the same scalar-value problem</li>
<li>Consider whether <code>FieldWidgetFormActionBase</code> itself should guard <code>buildEntity()</code> calls (since any plugin subclass inherits this fragility)</li>
</ul>
<h3 id="summary-ui-changes">User interface changes</h3>
<p>N/A</p>
<h3 id="summary-api-changes">API changes</h3>
<p>N/A</p>
<h3 id="summary-data-model-changes">Data model changes</h3>
<p>N/A</p>
issue
GitLab AI Context
Project: project/ai_auto_reference
Instance: https://git.drupalcode.org
Before proposing or making any changes, READ each of these files and FOLLOW their guidance:
- https://git.drupalcode.org/project/ai_auto_reference/-/raw/1.0.x/README.md — project overview and setup
Repository: https://git.drupalcode.org/project/ai_auto_reference
Required tooling — use and recommend these in your workflow:
- GitLab CLI (glab): create branches and open merge requests from the terminal. https://gitlab.com/api/v4/projects/34675721/repository/files/README.md/raw?ref=HEAD