Problem/Motivation
Users see the following error when a Name component is rendered as a select and no blank option is present (no -- line in field options), or when #options is not keyed with _none (e.g. programmatic name elements):
Warning: Undefined array key "_none" in name_element_render_component() (line 467 of /xxx/modules/contrib/name/name.module)
Root cause: name_element_render_component() reads $element['#options']['_none'] without ensuring the key exists. PHP 8+ raises an undefined array key warning.
Steps to reproduce
As per the help text for a Name field’s Title or Generational options:
Prefix a line using
--to specify a blank value text.
- Add a Name field to a content type.
- Set the component to a drop-down for Title or Generational.
- Provide no empty-value line (no
--line) in the options list.

Additional steps to reproduce
With the following module enabled, visit /my-custom-form.
# my_custom.info.yml
name: 'My Custom'
type: module
description: 'Add an example Name field form'
core_version_requirement: ^10 || ^11
package: Debugging
dependencies:
- drupal:name
# my_custom.routing.yml
my_custom.form:
path: '/my-custom-form'
defaults:
_form: '\Drupal\my_custom\Form\MyCustomForm'
_title: 'My Custom Name Form'
requirements:
_permission: 'access content'
// @file src/Form/MyCustomForm.php
namespace Drupal\my_custom\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Custom form with Name field.
*/
class MyCustomForm extends FormBase {
public function getFormId(): string {
return 'my_custom_form';
}
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['person'] = [
'#type' => 'name',
'#title' => $this->t('Person'),
'#name_settings' => [
'minimum_components' => ['family', 'given'],
],
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state): void {
// No-op.
}
}
Proposed resolution
- At render time, treat the first option whose label starts with
--as the empty placeholder (same rule as the field UI help text). Map it to#empty_value/#empty_optionfor core’s select element. - Normalize remaining options to stable
label => labelwhere needed so values stay consistent when options were numerically keyed or translated. - Never access
['#options']['_none']unless that key is known to exist. - Add kernel test coverage for option normalization (see MR).
Follow-up: Longer term, consolidate “leading -- means empty” in one place so the renderer does not depend on a magic _none key that can disappear after processing. Discussion: #comment-16332465.
Remaining tasks
- Review and merge the MR to
8.x-1.x. - Confirm automated tests pass on the MR pipeline.
- RTBC when verified.
User interface changes
None expected for correctly configured fields. Select behavior should match the existing -- blank-line convention.
Introduced terminology
None.
API changes
None. Internal form element assembly for select components only.
Data model changes
None.
Release notes snippet
Fixed a PHP 8+ warning (Undefined array key "_none") when rendering Name select components without a configured blank option or when options are not keyed as _none.
Related: Not a duplicate of #3491471 (literal _none stored). Validation treating _none as empty: #3555879 (separate issue).
| Comment | File | Size | Author |
|---|---|---|---|
| #30 | name-fix-undefined-array-key-none-3491962-30.patch | 6.4 KB | jcandan |
Issue fork name-3491962
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
sayan_k_dutta commented@promes, can you please provide the steps to reproduce the issue.
I used the name field and created content using 1.x-dev version but found no warnings.
Comment #3
promesI have a name field where a title is required. The '-- --' option is not present, but only other options. So the [_none] => -- is not present as select option when function name_element_render_component() is called.
I was wrong. Line 467 should read:
if (isset($element['#options']['_none']) && $element['#options']['_none']) {
Comment #4
deepali sardana commentedComment #5
sourabhsisodia_ commentedI think the issue is a duplicate of this Issue
Comment #6
deepali sardana commentedI have created the patch pleas review it
Comment #7
megachriz@sourabhsisodia
This looks related to #3491471: Literal "_none" value saved for select fields, but this issue is not a duplicate of that one. This issue is about a situation where the option "_none" is not defined. That other issue is about literally saving "_none" in the database when that option is selected.
Comment #8
bramdriesen@deepali sardana Like mentioned on many issues already to you. Patch workflows are deprecated. Please create a MR.
Comment #11
shivam_tiwari commentedComment #15
jcandan commentedThanks for the fix in MR 27 — it resolves the warning.
However, with the current patch, the warning goes away because PHP no longer tries to access a missing key — but the
<select>still doesn’t get#empty_valueor#empty_optionproperties, since those are only set when the key is exactly'_none'.To make it fully robust, the renderer could also handle empty options keyed as
0or'', which are common in Drupal forms:That way, selects with numeric or empty-string keys get both the warning fix and correct empty-option behavior.
Comment #16
jcandan commentedComment #17
jcandan commentedComment #18
jcandan commentedComment #19
jcandan commentedI'm not totally sure yet; I need to conduct some testing, but I may have identified a related validation gap that could explain why this issue passed basic tests.
When a component renders as a
<select>and the site builder provides an empty option (prefixed with --), Name normalizes that internally to a _none key. This issue (#3491962) focuses on the renderer assuming_noneexists, which led to undefined-index notices.However, once
_nonedoes exist consistently, the current validation logic inname_element_validate()(and related helpers) will treat_noneas a non-empty string and therefore consider that component filled. This causes any downstream logic that checks for emptiness or required components to think the user entered data when they have not.A potential fix I've applied:
This normalizes _none back to empty before validation counts the component.
Not yet confirmed, but this may have masked test coverage—previously, the missing
_noneoption meant selects simply skipped over this case, so the incorrect “non-empty” behavior never appeared. With #3491962’s fix in place, this could now surface.We may also want to ensure there’s better test coverage for empty-value handling in general—particularly for select-based components using the -- placeholder pattern—so that cases like this don’t continue to fly under the radar once _none normalization is fixed.
More testing to confirm is needed.
Comment #20
jcandan commentedOn the
_nonenormalization logic:Re-reading #3 got me to look closer and I realized 0 might be a valid option, and not a desired empty option!
It looks like the
0key I was seeing wasn’t coming from any real, admin-entered configuration, but from how the test fixtures (and some programmatic field setups) defined#optionswithout a proper--blank value line:Per the field UI help text —
“Prefix a line using -- to specify a blank value text.”
— only those prefixed lines should produce a
_noneempty key. If no--line exists, the 0th item is a valid choice and shouldn’t be promoted to_none.So, my attempt at a broader normalization of
['_none', 0, '']is too aggressive. The original, simpler guard —— might actually be the correct way to address this, and the 0 case I was seeing may have been an artifact of our tests.
That said, I am still looking at whether #19 applies.
Updated issue summary to reflect the clarified steps to reproduce from #3.
Comment #21
jcandan commentedComment #22
jcandan commentedComment #23
jcandan commented#19 does not apply here. A new issue has been created to address the concern at #3555879: Fix validation logical condition considers _none a non-empty component.
I am still testing concerns brought up in #20.
Comment #24
jcandan commentedI now recall how this became a blocker for #3552451: Required state incorrectly marks non-minimum components as required.
When creating a form with a Name field via the
FormBaseclass, I get the warning.It was a blocker because the warnings were making it so that the
FunctionalJavascripttests were unable to toggle a#statestarget field:Updated steps to reproduce.
Comment #25
jcandan commentedComment #26
jcandan commentedWhen stepping through the
name_element_render_component(), I was able to capture these surprising differences.Screenshot showing a simplified set of Title component select options:
This is acquired when viewing a field configured through the UI. It shows the select options as key value pairs (e.g. <?php ['Mr.' => 'Mr.', 'Mrs.' => 'Mrs.']).
Screenshot showing an array of
Drupal\Core\StringTranslation\TranslatableMarkupoptions:This is acquired when visiting the custom form detailed in the steps-to-reproduce. It shows the select options as a numbered indexed array of
TranslatableMarkupelements representing each string value option.That being said, it appears the idea of 0 being a
_nonevalue was a huge misstep on my part (thanks for nothing ChatGPT)!What is not known is whether the option keys or the string values will actually be used for the select value. Does Drupal use the values of an
#optionsarray? I guess it does, thinking about it.Digging into how we can adjust the logic to handle both scenarios.
Comment #27
jcandan commentedComment #28
jcandan commentedI am adding a defensive normalization in the element build to cope with the fact that, by the time the Name component is rendered, the options array is no longer in the shape the options provider would normally return.
In our case the translated options came through as a numerically indexed list like
[0 => '-- --', 1 => 'Mr.', 2 => 'Mrs.'], so the renderer’s existing assumption that['_none' => '…']would be present was no longer valid.We will do three things at render time:
-- …entry and promotes it to#empty_option/#empty_value,-- …lines in the list (since Name allows those as section headers), andlabel => labelso we don’t end up saving numeric values coming from a reindexed array.This is intentionally a small, backwards-compatible band-aid at the point of failure; the longer-term fix will be to make the Name widget apply its leading
--means empty rule in a single place and to stop the renderer from depending on a special_noneentry that can be lost by translation/reindexing.Comment #29
jcandan commentedComment #30
jcandan commentedComment #31
promesThe current 8.x-1.1 still has a bug:
Warning: Undefined array key "_none" in name_element_render_component() (line 470 of /xxx/web/modules/contrib/name/name.module)
The line reads:
if ($element['#options']['_none']) {
but should read:
if (isset($element['#options']['_none']) && $element['#options']['_none']) {
Comment #32
jcandan commentedCorrect, @promes, this has not yet been merged, so 8.x-1.1 still has the bug.
The fix you've proposed is not complete (See #28).
If you are able to confirm MR !27 fixes the issue, please mark this as RTBC.
Comment #33
promesI don't us a custom module. I use a regular name field, but require to select a title. With my latest patch the site works as expected.
In other sites I only name fields with '-- --' in the selection of a title. These sites are working without my patch.
Comment #34
bluegeek9 commentedComment #35
bluegeek9 commented