Following an upgrade to jsonapi release 1.22, I am getting the following error in the log:
LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\jsonapi\ResourceResponse. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (line 154 of /home/james/vmg/fbportal/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).
I have used Postman to make a request:
{{protocol}}://{{host}}/jsonapi/node/article?_format=api_json
where {{protocol}} is "http" and {{host}} is "fbportal.helene.lan" (which is my development environment).
The response is:
{
"errors": [
{
"title": "Internal Server Error",
"status": 500,
"detail": "The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\\jsonapi\\ResourceResponse.",
"links": {
"info": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1"
},
"code": 0
}
]
}I downgraded the environment to jsonapi release 1.21 and the error message disappeared, with the expected list of articles being returned.
I also removed the custom fields I had added to the article content type, but the error persisted with jsonapi release 1.22.
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | 2984964-22.patch | 10.32 KB | wim leers |
| #22 | interdiff.txt | 633 bytes | wim leers |
| #21 | 2984964-21.patch | 10.19 KB | wim leers |
| #21 | 2984964-21-test_only_FAIL.patch | 1.45 KB | wim leers |
| #20 | 2984964-20.patch | 8.78 KB | wim leers |
Comments
Comment #2
jayelless commentedInspecting the code in EarlyrenderingControllerWrapperSubscriber
the value of $early_rendering_bubbleable_metadata contains only
Does this mean that the problem lies with node access permissions? My site is using the group module, although articles are not part of any group. I will try this problem on an environment that is not using group.
Comment #3
jordan.jamous commentedSame issue here!
Comment #4
jayelless commentedI used a separate instance of D8 (8.6.x-dev), with the jsonapi, group, and taxonomy modules installed. The jsonapi response to the query used above was the expected list of articles.
I upgraded my development environment to D8.6.x-dev, but the error still persisits???
Comment #5
jayelless commentedI deleted all the groups and group_content entities from the database and then rebuilt the permissions in my development environment, but the leaked metadata error was still reported. However, when I un-installed the group node (gnode) module, the error disappeared and th expected list of articles was returned.
I then re-installed the group node module, and rebuilt permissions, but the error did not come back??? It transpired that doing a drush cache-rebuild was not sufficient. I had to truncate the cache tables in the database to observe the re-appearance of the error message.
Following a series of tests, I can confirm that if the group node module is installed, node access permissions rebuilt, and caches properly cleared, then the leaked metadata message is reported. If the group module is un-installed, node access permissions rebuilt (happens automatically), and caches properly cleared, then the expected list of content is returned. There is no need to have any groups defined, nor to have any group_content in the database.
Comment #6
jayelless commentedIt appears that this issue should really be on the group issue queue. Moving there.
Comment #7
jayelless commentedComment #8
jayelless commentedFurther testing shows that the problem is present when the nodeaccess module is installed, so this issue appears to be generic when any node access functionality is enabled. Moving this issue back to project jsonapi.
To check: install and enable nodeaccess, rebuild the access permissions, and truncate the cache tables.
Comment #9
jayelless commentedThe leaked metadata of "user.node_grants:view" is added to the cacheContexts by the following code in hook_query_node_access_alter() in node.module:
So why is the metadata not being correctly bubbled?
Comment #10
jayelless commentedThe change from v1.21 to 1.22 that has revealed this error was the replacement of the following code
by the single line
It would appear that the code block above was added previously to address a similar issue as discussed in #2952714: Group module's GroupAccessResult::allowedIfHasGroupPermission(s)() does not include cacheability. However, the issue appears to be more significant than the group module or the nodeaccess module.
I can also confirm that the same issue is present with jsonapi release 2.x-dev. Changing the issue metadata.
Comment #11
david spiessens commentedSame issue here. We don't use the group module.
Comment #12
pwolanin commentedI seem to be seeing the same. I think it relates to our use of the consumer_image_styles module or maybe filefield_paths module. The problem code has cache context of url.site so likely related to Url generation.
Comment #13
wim leersThanks for reporting!
On it :)
Comment #14
wim leers@pwolanin Created #2985403: ImageEntityNormalizer::buildVariantValues() does not handle cacheability correctly for that.
Comment #15
wim leersMore accurate title.
(Reproduced the problem.)
Comment #16
wim leers#2948666: Remove JSON API's use of $context['cacheable_metadata'] is the refactor/clean-up commit that allows this to manifest.
Comment #17
wim leers#2948666: Remove JSON API's use of $context['cacheable_metadata'] is still a good thing: that was catching bubbled cacheability at a very very broad level.
We just need to bring back a little bit of that, for query execution. And fortunately, there's only a single place in all of JSON API where we do that. 👍
Most of the attached patch is updating boilerplate to get the
rendererservice injected into the right place.Thank you for this important bug discovery!
P.S.: hey look at that, a certain @gabesullice fellow filed an issue for the general version of this nearly two years ago: #2794385: Node grants make it impossible to return a CacheableResponse from a controller :)
Comment #19
jayelless commentedThanks for the patch. I can confirm that the patch in #17 has fixed the problem in both of my environments:
I will leave the status on "Needs work" as the patch failed testing.
Comment #20
wim leersThis should be green.
But this still needs explicit test coverage. On it.
Comment #21
wim leersThe test-only patch is also the interdiff.
Comment #22
wim leersMight as well explicitly test this.
Comment #24
gabesulliceMan, it's so weird that we need
@rendererto execute a query...But, I think this is a small and proper change. RTBC :)
Comment #26
wim leers#24: no disagreement there. The query system sadly was never updated to pass on relevant cacheability in a sane way… this was the unfortunate work-around so we could ship D8.
Credited everybody who helped shape this patch! Thanks! 🙏
Comment #28
steven.wichers commentedThis fixes the issue on the 1.x branch as well.
Comment #29
gabesulliceI think this issue deserves to be backported to 1.x in the #2990908: [1.x] Drupal core compatibility release
Comment #30
wim leersLet's reopen this when we actually work on it; otherwise it's gonna be confusing. (In core we have the principle of opening a separate issue for a backport to avoid this same confusion, but I think that's disproportionately onerous in the case of JSON API.)
Comment #32
rpayanmMoving to Drupal core's issue queue.
I'm working on https://www.drupal.org/project/drupal/issues/3122113