Why is my form only redirected sometimes? I want to have a user register, and be redirected to a node create form. Here's how I'm doing it thus far. 

The setup

I have a route, my_module.register that is handled by MyController::register(). It returns the user register form, like so:



class MyController extends ControllerBase {
  public function register() {
    return $this-&gt;entityFormBuilder-&gt;getForm(User::create([]), 'register');
  }
}


I also have this service, my_module.form_alter_service (just pretend all the implied dependency injection is there):

class MyFormAlterService {

  public function registerFormAlter(array &amp;$form, FormStateInterface $form_state) {
    if ($this-&gt;currentRouteMatch-&gt;getRouteName() == 'my_module.register') {
      $form['actions']['submit']['#submit'][] = [$this, 'redirectToAddNode'];
    }
  }

  public static function redirectToAddNode(array &amp;$form, FormStateInterface $form_state) {
    $form_state-&gt;setRedirect(/* imagine a node form route here */);
  }

}


I have also implemented hook_form_FORM_ID_alter():

function my_module_form_user_register_form_alter(array $form, FormStateInterface $form_state) {
  \Drupal::service('my_module.form_alter_service')-&gt;registerFormAlter($form, $form_state);
}


The expected behavior

I fill out the user register form at /my_module/register, hit submit, and am taken to the desired node add form.

What happens instead

I fill out the user register form at /my_module/register and end up on my user edit page.

But then, if I delete that user, clear the cache, and repeat the process with the exact same credentials, it works as expected.

What I know


I am getting debugging output from every part of the process, so I know each part is running.
I am using the exact same pattern for the login form; identical code in the form alter, and that works great.
I can also get debug output from Drupal/user/EventSubscriber/AccessDeniedSubscriber::onException() which redirects authenticated users who are visiting the user.register route to their edit page. So I know that's causing the unwanted redirect, when the unwanted redirect happens.
I tried removing the user.roles:authenticated cache context from the form, and adding user, but that didn't seem to change things.


The actual question(s)

Why is the form initially not respecting the redirect I set in the submit handler? Why does a cache clear change that behavior?
The cause for the erratic behavior is probably the condition for the current route name in the form alter method. The form is not necessarily built in the same request as the custom controller, it could be served from cache or built in a POST request.

At the moment you have the condition for the route name because the controller invokes the default register form and the form alter doesn't know where it is called from. So you need to make the form distinguishable, for example by a different form handler, a field value in the new entity before you hand it over to the form builder or put the form alter code in a custom form class extending the core user form.

BTW why are you not redirecting by the destination query string you can set on the user register link, then you don't need code?