Problem/Motivation
If you have a route that uses the bundle parameter, and a local task linked to that route, when you visit a node that is not in one of the bundles defined the local task block gets a max-age of 0. This is because ParamConverterManager throws a ParamNotConvertedException if the entity returned is NULL, which AccessManager catches and adds the max-age 0:
// Uncacheable because conversion of the parameter may not have been
// possible due to dynamic circumstances.
$result = AccessResult::forbidden()->setCacheMaxAge(0);
return $return_as_object ? $result : $result->isAllowed();
LocalTaskManager calls the checkedNamedRoute method of the access manager.
If you enable http.response.debug_cacheability_headers: true the whole page gets a 0 (Uncacheable) warning for x-drupal-cache-max-age response header.
This is mitigated by the fact that the localTasksBlocks returns True for the createPlaceholder method which means it is using a lazy builder by default. So actually the page is cacheable but the header is confusing and it is really hard to track down what is setting the max-age property.
Steps to reproduce
Create a route that uses the bundle option:
my_module.my_route:
path: /node/{node}/do-something
defaults:
_title: 'Do something route'
_controller: '\Drupal\my_module\Controller\MyController::index'
requirements:
_permission: 'administer search_api'
_entity_access: 'node.update'
options:
parameters:
node:
type: entity:node
bundle:
- product_list_page
Create a local task and assign the route to it:
my_module.my_task:
route_name: my_module.my_route:
title: 'Do something task'
base_route: entity.node.canonical
Set this to true in services.yml
http.response.debug_cacheability_headers: true
Now view any node that is not in the bundle option. The x-drupal-cache-max-age response header will now be: 0 (Uncacheable).
Proposed resolution
I don't know what the best solution is. Either setting max-age to 0 is inappropriate or, since the local tasks use a lazy builder anyway maybe they shouldn't be used in determining if the page is cacheable when it bubbles up?
Comments