Route callback for RegisterForm results in Call to a member function getEntityTypeId() on null My objective: Let say there is a role named "author". I would like to have a registration form having this path: /register/author, when the user submit, he/she will get the author role (same for any other roles like /register/another_role)

Here is what I have done:

1-Creating a route: last argument will be the role name

mymodule.register:
  path: '/register/{role}'
  defaults:
    _form: 'Drupal\mymodule\Form\RegisterByRole'
    _title: 'Register by role'
  requirements:
    _permission: 'access content'


2-Extending the RegisterForm Class

class RegisterByRole extends RegisterForm
{
    public function form(array $form, FormStateInterface $form_state, $role = null)
    {
        $form = parent::form($form, $form_state);
        if (role_is_allowed($role)) {
            $form['test'] = [
                '#markup' =&gt; '&lt;p&gt;Test:' . $role
            ];
        }
        return $form;
    }
}


Of course I must change the submit function to assign the role, but I already have the following error when visiting the /register/author path:

Error: Call to a member function getEntityTypeId() on null in Drupal\Core\Entity\EntityForm-&gt;getBaseFormId() (line 111 of core/lib/Drupal/Core/Entity/EntityForm.php).


I found that if I add the __construct and the create functions in the RegisterByRole class definition, the getBaseFormId error disappears... But I don't understand why?... And more annoying, I couldn't get the value of my $role argument (last arg of the route).

What is wrong in my plan?
I believe the problem is here:

_form: 'Drupal\mymodule\Form\RegisterByRole'


You need to use _entity_form rather than _entity, as the RegisterForm is actually an entity form for the User entity, as described in the Entity declaration for \Drupal\user\Entity\User:

"form" = {
  ...
  "register" = "Drupal\user\RegisterForm"
},


But to do this, you'll have to register a new form op for that class. You can do this in hook_entity_type_alter():

function hook_entity_type_alter(array &amp;$entity_types) {
  $user = &amp;$entity_types['user'];
  $user-&gt;setFormClass('role_registration', 'Drupal\example\Form\RegisterByRole');
}


Then, back in your route, you'll remove _form and instead implement_entity_form, setting it to to user.role_registration:

_entity_form: 'user.role_registration'