Problem/Motivation
When you click "Add field group" while managing a non-default form mode or view mode, the new group is not created on the mode you are editing. It is silently created on the default mode instead.
This is a regression introduced by the coding standards cleanup in #3490746: Fix ESLint, phpcs, phpstan, cspell coding standards (commit 9dd5c102, 2026-06-11), so it affects 4.x-dev from that date on.
Steps to reproduce
- Install field_group 4.x-dev (commit 9dd5c102 or later).
- Add a second form mode to a content type and enable it under "Custom display settings".
- Go to "Manage form display" for that new form mode and click "Add field group".
- Create a group of any type.
- Result: the current form mode does not have the new group. It was created on the default form mode. The same happens with view modes on "Manage display".
Proposed resolution
The cause is a one-line mistake in the #3490746: Fix ESLint, phpcs, phpstan, cspell coding standards cleanup. FieldGroupAddForm::buildForm() used $this->getRequest()->get('form_mode_name') to read the mode. Because phpstan discourages Request::get(), it was replaced like this:
- $this->mode = $this->getRequest()->get('form_mode_name'); + $this->mode = $this->getRequest()->request->get('form_mode_name');
That replacement looks in the wrong place. form_mode_name and view_mode_name are route parameters, and route parameters live in $request->attributes. The $request->request bag only holds POST body fields, so the lookup now always returns NULL and the code falls back to 'default'.
The fix is to read from the attributes bag, which is what the old Request::get() call was finding all along:
- $this->mode = $this->getRequest()->request->get('form_mode_name'); + $this->mode = $this->getRequest()->attributes->get('form_mode_name');
and the same for view_mode_name two lines below.
The attached patch contains the two-line fix plus a regression test, ManageDisplayTest::testCreateGroupOnNonDefaultMode(). The test creates a custom form mode and a custom view mode, adds a group through the UI on each, and asserts the group ends up on that mode and not on default. It fails on current 4.x HEAD and passes with the fix.
Issue fork field_group-3614498
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
loze commentedComment #4
loze commentedComment #5
csakiistvanComment #6
csakiistvanEnvironment
Prerequisites
core/onceis normally already loaded by another core library, so the missing declaration only surfaces aReferenceError: once is not definedin edge cases with minimal library loading. It is verified by inspecting the resolved library dependencies rather than through the browser.Steps
core/onceto the dependencies of thedetails_validation,tab_validation, andtabs_validationlibraries infield_group.libraries.yml.ddev drush crddev drush php-eval 'foreach (["details_validation","tab_validation","tabs_validation"] as $n) { $l = \Drupal::service("library.discovery")->getLibraryByName("field_group", $n); print $n . ": " . implode(", ", $l["dependencies"]) . "\n"; }'Expected results
core/jqueryandcore/onceas dependencies.oncefunction used in the corresponding JavaScript files is guaranteed to be available.Actual results
Before the fix, the
details_validation,tab_validation, andtabs_validationlibraries declared onlycore/jquery, even though their JavaScript files receiveonceas a parameter and call it directly, leaving thecore/oncedependency undeclared. After the fix, all three libraries resolve withcore/jqueryandcore/once, so theoncefunction is always loaded before the scripts run.Testing produced with the assistance of an LLM.
Comment #7
anybodyThank you all! Merging!
Comment #9
anybody