Problem

  • Error message displayed after writing code for a form:

    InvalidArgumentException: The form argument Drupal\mymodule\Form\MymoduleLoginForm is not a valid form. in Drupal\Core\Form\FormBuilder->getFormId() (line 190 of core/lib/Drupal/Core/Form/FormBuilder.php)

Cause

  • Class name did not match filename, so the form could not be loaded.

Details

  • Error message suggests that something WITHIN the form is not valid, so I'm trying to spot an error in the completely wrong place.

Proposed solution

  1. Change error message to state clearly that the system wasn't able to locate / load the form.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sun created an issue. See original summary.

sun’s picture

Title: DX: Insufficient error message "" » DX: Insufficient error message "The form argument is not a valid form."
sun’s picture

Issue summary: View changes

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

morsok’s picture

Ah just got bitten by that, looking everywhere when It was a simple typo (missing uppercase in the class name).

jhedstrom’s picture

Status: Active » Needs review
FileSize
997 bytes

This splits the exception into 2, for the 2 different potential causes.

jhedstrom’s picture

Although, I wonder if this is an appropriate place to use `assert()` instead?

Status: Needs review » Needs work

The last submitted patch, 6: 2965929-06.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jhedstrom’s picture

Status: Needs work » Needs review
FileSize
2.92 KB
3.08 KB

This updates the test, and adds coverage for the new logic and exception text.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

kkalashnikov’s picture

Assigned: Unassigned » kkalashnikov
kkalashnikov’s picture

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

dimitriskr’s picture

This patch helped a lot

I uploaded a new version of the last patch where it adds a space after an elseif()

DanielVeza’s picture

Status: Needs review » Needs work
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -193,8 +193,11 @@ public function getFormId($form_arg, FormStateInterface &$form_state) {
+    elseif (!($form_arg instanceof FormInterface)) {
+      throw new \InvalidArgumentException('The form argument ' . get_class($form_arg) . ' must be an instance of \Drupal\Core\Form\FormInterface.');

Does this need to be an elseif?

I also feel like the patch in #9 by @jhedstrom had more test coverage thats missing from this patch. I think that needs to be added back in.

Lendude’s picture

+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -193,8 +193,11 @@ public function getFormId($form_arg, FormStateInterface &$form_state) {
+      throw new \InvalidArgumentException('The form argument ' . get_class($form_arg) . ' must be an instance of \Drupal\Core\Form\FormInterface.');
     }

I think we use ::class now and not get_class()

dimitriskr’s picture

Status: Needs work » Needs review
FileSize
3.1 KB
1.46 KB

Here's the new patch with the suggested changes. I won't enable tests until you confirm the changes are the correct

@DanielVeza the elseif must be elseif because the if (!is_object($form_arg)) { checks $form_arg is object, but then we have to make sure it's instanceof FormInterface because here $form_state->setFormObject($form_arg); it expects an object of FormInterface

Lendude’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Sounds like a good addition, tests cover the new exception. Looks good.

  • catch committed 10400bd on 10.0.x
    Issue #2965929 by jhedstrom, dimitriskr, kkalashnikov, sun, Lendude,...
  • catch committed 12e26bd on 10.1.x
    Issue #2965929 by jhedstrom, dimitriskr, kkalashnikov, sun, Lendude,...
  • catch committed a12680a on 9.5.x
    Issue #2965929 by jhedstrom, dimitriskr, kkalashnikov, sun, Lendude,...
catch’s picture

Version: 9.4.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x, thanks!

longwave’s picture

This has broken compatibility with PHP 7.3 in 9.5.x, technically we don't support it any more but this currently causes so many errors DrupalCI cannot report them: https://www.drupal.org/pift-ci-job/2509655

The error is

PHP Fatal error:  Dynamic class names are not allowed in compile-time ::class fetch in /var/www/html/core/lib/Drupal/Core/Form/FormBuilder.php on line 200
dimitriskr’s picture

Ah interesting

So shall we use get_class() instead?

longwave’s picture

I think get_class() would work fine.

dimitriskr’s picture

Assigned: Unassigned » dimitriskr
Status: Fixed » Needs work

  • catch committed 751983c on 9.5.x
    Revert "Issue #2965929 by jhedstrom, dimitriskr, kkalashnikov, sun,...
catch’s picture

Reverted from 9.5.x, leaving needs work in case we want to backport a 7.3-friendly version, but we could also just leave this in 10.0.x

dimitriskr’s picture

Assigned: dimitriskr » Unassigned
Status: Needs work » Needs review
FileSize
3.1 KB

Here's the patch again, using get_class() instead of ::class to support PHP 7.3 and 7.4

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, thank you.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 83d2b0b and pushed to 9.5.x. Thanks!

  • alexpott committed 83d2b0b on 9.5.x
    Issue #2965929 by dimitriskr, jhedstrom, kkalashnikov, sun, Lendude,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.