Route access check for local task I've created a view with a page display, filtering on a specific node type. The view's URL is /admin/poi.

Now I want to create a local task, linking to this view, for all nodes of type poi. The local task is showing, but it is visible when viewing/editing any node type, not just my POIs.

wt_poi.routing.yml

wt_poi.admin_list:
  path: '/admin/poi'
  requirements:
    _permission: 'access administration pages'
    _custom_access: '\Drupal\wt_poi\Controller\WtPoiController::isAllowedPoiAdminList'
  options:
    _admin_route: true


wt_poi.links.task.yml

wt_poi.list_overview:
  route_name: wt_poi.admin_list
  base_route: entity.node.canonical
  title: 'List all POIs'
  weight: -9999


src/Controller/WtPoiController.php

&lt;?php

namespace Drupal\wt_poi\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;

/**
 * Controller for the POI node type tasks.
 *
 */
class WtPoiController extends ControllerBase {

  /**
   * Used to limit visibility of local task "List" to POI node type
   */
  public function isAllowedPoiAdminList() {
    $bundle = false;
    $node = \Drupal::routeMatch()-&gt;getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      $bundle = $node-&gt;bundle();
    }
    return AccessResult::forbiddenIf($bundle !== 'poi');
  }
}


Why is my _custom_access check not hiding the local task on other node types?

UPDATE: There seems to be an access check, but it is coming from "Access" in views module "Page settings" and my own access check is completly ignored. Best case would be my access check in addition to the view's access check, in a pinch I would prefer my own custom check replacing the view's access check.
I've found a workaround. When I add the view's URL as path in routing.yml, Drupal always used the view's access check. So instead of directly using the view's path, I wrote a simple redirect controller in order to get an alternative path.

wt_poi.routing.yml

wt_poi.admin_list:
  path: '/admin/poi-redirect'
  defaults:
    _controller: '\Drupal\wt_poi\Controller\WtPoiController::redirectToPoiAdminList'
  requirements:
    _permission: 'administer nodes'
    _custom_access: '\Drupal\wt_poi\Controller\WtPoiController::isAllowedPoiAdminList'
  options:
    _admin_route: true


wt_poi.links.task.yml remains unchanged

src/Controller/WtPoiController.php

&lt;?php

namespace Drupal\wt_poi\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;

/**
 * Controller for the POI node type tasks.
 *
 */
class WtPoiController extends ControllerBase {

  /**
   * The only purpose of this controller is to provide an
   * alternative path to the POI view, so we can attach an
   * _custom_access check to it.
   */
  public function redirectToPoiAdminList() {
    // redirecting to a view: view.VIEW_MACHINE_NAME.DISPLAY_MACHINE_NAME
    return $this-&gt;redirect('view.poi.admin_list');
  }

  /**
   * Used to limit visibility of local Task "List" to POI node types
   */
  public function isAllowedPoiAdminList() {
    $bundle = false;
    $route = \Drupal::routeMatch();
    $routeName = $route-&gt;getRouteName();
    $node = $route-&gt;getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      $bundle = $node-&gt;bundle();
    }
    // the first part ensures the local task is shown on node pages,
    // the second part makes sure it also works during the redirection itself
    return AccessResult::allowedIf($bundle === 'poi' || $routeName === 'wt_poi.admin_list');
  }
}


Two remarks:

A) Remember that the user still has to pass the view's own permission check after the redirection (and this is a good thing, otherwise anybody knowing the alternative URL could bypass the access check).

B) The access check must use an allowedIf($positiveCondition). Do not use an forbiddenIf($negativeCondition), because it only returns forbidden or neutral, which always hides the local task.

My solution still feels a bit hacky, and I still would be open for a cleaner solution, but at least it does everything I need.