How to unflag/reset a flag again, when matching some conditions in onFlag event? in my custom module I have an event subscriber service for flag module. I used the tutorial here as a base for learning: Link to Tutorial
Here is my code:
namespace Drupal\MYMODULE\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\flag\Event\FlagEvents;
use Drupal\flag\Event\FlaggingEvent;
use Drupal\flag\Event\UnflaggingEvent;
use Drupal\user\UserInterface;
use Drupal\user\Entity\User;

class MYMODULEFlagSubscriber implements EventSubscriberInterface {

  /**
   * Do the logic when the upgrade flag is triggered to flag.
   */
  public function onFlag(FlaggingEvent $event) {
    $flagging = $event-&gt;getFlagging();
    $flag = $flagging-&gt;getFlag();
    $flag_machine_name = $flag-&gt;id();
    if ($flag_machine_name === 'my_awesome_flag') {
      $entity_nid = $flagging-&gt;getFlaggable()-&gt;id();
      $user = User::load($entity_nid);
      $user_is_active = $user-&gt;isActive();
      $field_1 = $user-&gt;get('field_1')-&gt;value;
      $field_2 = $user-&gt;get('field_2')-&gt;value;
      $break_with_error = FALSE;
      $upgrade_message = '';
      $roles_to_ignore = [
        'administrator_junior',
        'team_sales',
        'administrator',
      ];
      if (!$user-&gt;hasRole('authenticated_level_2')) {
        if (($user_is_active == TRUE) &amp;&amp; ($field_1 == 1) &amp;&amp; ($field_2 == 1)) {
          foreach ($roles_to_ignore as $role_to_ignore) {
            if ($user-&gt;hasRole($role_to_ignore)) {
              $break_with_error = TRUE;
              $upgrade_message = 'The User has a company role already and can not being upgraded as a Level 2 user.';
              break;
            }
          }
        }
        else {
          $break_with_error = TRUE;
          $upgrade_message = 'The User can not being upgraded as a Level 2 User. Reasons: 2. The account is not activated yet, 3. The user has not yet checked field 2';
        }
      }
      else {
        $break_with_error = TRUE;
        $upgrade_message = 'The User was upgraded as a Level 2 User already.';
      }

      switch ($break_with_error) {
        case TRUE:
          \Drupal::messenger()-&gt;addError($upgrade_message);
          $flagging-&gt;unflag($flag_machine_name, $entity_nid);
          return;

        case FALSE:
          $user-&gt;addRole('authenticated_level_2');
          $user-&gt;save();
          \Drupal::messenger()-&gt;addStatus('The User was upgraded as a Level 2 User sucessfully.');
          return;
      }

    }
  }

My Problem is
How can I unflag the flag again, when my logic checks settings and my variable $break_with_error becomes true?
$flagging-&gt;unflag($flag_machine_name, $entity_nid);

throws me an PHP error.
Update:
My intention was the following:
I use the flag here as a substitute for a link/button to trigger the &quot;business logic&quot; checks and to give the user a additional role with more privileges if the checks are passed.
In my opinion it's a easy way to quickly have a link/button in multiple variants (e.g. in a view or as a field in user account). Another advantage is, that other people (in my case sales team or other admins) see the business logic checks have performed already when the user entity is flagged. But in case the logic checks are failing, the user entity should unflagged again.
For other opportunities to have a &quot;business logic trigger&quot; I'm open and thankful of course.
I'm guessing the problem is that in the onFlag event, the flag is still being created, so it can't be unflagged because it hasn't been fully saved yet.
But I think the bigger problem is that your code has a logic error-- validation should happen before the action, not after the action.
It looks like you are trying to do this:

When a user is flagged,
check if the flag meets certain &quot;unflag&quot; conditions,
if the conditions are met, unflag the user.

However, validation in Drupal usually is applied before something happens, not after.  Validation is not supposed to be a kill switch to stop a problem; you should stop the problem before it happens.
One reason to stop the problem before it happens is that you later may add code that does something when a node is flagged (for example, in hook_entity_insert()); in such a case, you would also have to undo the code in your flag event subscriber.
So, what you probably want to do is apply the validation login in hook_form_alter() so you can stop the flagging before it happens.