I want to make a menu link disappear when a user doesn't have permission to use it. I tried this code:

function some_module_menu_links_discovered_alter(&$links) {
  $user = \Drupal::currentUser();

  file_put_contents(DRUPAL_ROOT . '/logs/permission.txt', var_export($user->hasPermission('access some module config'), true));
  file_put_contents(DRUPAL_ROOT . '/logs/roles.txt', var_export($user->getRoles(), true));
  file_put_contents(DRUPAL_ROOT . '/logs/id.txt', var_export($user->id(), true));

  if (\Drupal::moduleHandler()->moduleExists('some_module')) {
    if (!$user->hasPermission('access some module config')) {
      $links['some_module.admin']['parent'] = '';

And it didn't know that the logged in user existed. I was logged in as an administrator, and it thought I was anonymous. I tried the same code in another hook, and it worked. So, I'm curious:

  1. Why does this hook load before currentUser knows I'm logged in?
  2. And, are there other hooks like this?
  3. Should I try to figure out the current user through another more low-level method?
  4. Or, is there another way to make a menu link disappear when a user doesn't have permission to view it?

EDIT: Providing code to show what I've done. The menu link is not disappearing when users don't have access to the route it links to.

  path: '/admin/config/system/some_path'
    _form: '\Drupal\some_module\Form\SomeModuleForm'
    _title: 'Some title...'
    _permission: 'access some module config' 

The users do not have the access some module config permission, yet the menu link is showing up for them. When they click on it, they get an access denied page.

1 Answer 1


Question in the title: Hook fires before current_user service can identify current user

The menu discovery process is not that dynamically, only runs when you clear the cache or make changes that need a rebuild. So the current user while rebuilding the menu has nothing to do with the current user of a request when the menu is displayed.

I want to make a menu link disappear when a user doesn't have permission to use it.

About the question behind this, what do you not like about the default behavior? Drupal doesn't show menu items the user has no permission for. If you want to do more adjustments probably the best place is in preprocess.

  • Thanks for the info about the hook. The menu link is not disappearing for me, though. I'm not sure why. Mar 7, 2017 at 16:42
  • 1
    Found two explanations, first the user could have the permission "Link to any page", this would override any permission set in the route, second the menu link has an absolute path instead of a relative internal one. But there are probably more. I would try a standard permission from core to test this, to check if there is something wrong with the module.
    – 4uk4
    Mar 7, 2017 at 17:15
  • Aww, that was it, 4k4, thanks. The Link to any page permission was active for the user. There are so many permissions, I don't even notice some of them. Mar 7, 2017 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.