During testing of my new theme I get the following error message: Recursive rendering detected when rendering entity media: 1, using the field_my_image field on the image_my_image bundle. Aborting rendering.
For site-building I designed building-blocks with Paragraphs. For media management I use Media. Basically, the theme works fine. However, when I put 20+ paragraphs on one node the above error message occurs.
Is there a way to increase the recursive protection value over 20 or is there a way to avoid recursive rendering from the start?
Architecture:
Media Management: Media bundles > (are used in)
Building blocks: Paragraphs > Paragraphs entity reference revisions
Layout: Paragraphs entity reference revisions on Content types.
Comments
Comment #2
Ralf Eisler commentedI found a solution for the problem. Instead of using Views to place content in regions, I separated content with page views.
Comment #3
phenaproximaRecursive rendering almost always means that a mistake was made somewhere. I don't see why one would ever want to do it, because it's very dangerous in terms of resource usage and server health. I am not aware of any way to raise the protection value, but that seems like an unwise move. Better to simply construct things in a way that will not render recursively :)
Comment #4
briangeorge commentedThanks @phenaproxima this actually affects valid scenarios. It is consistently reproducible simply by having the same paragraph render over 20 times. We won't take the time to describe such a scenario here, suffice it to say it affects at least one real world project scenario.
The following code appears in
\Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsEntityFormatter::viewElements()This is obviously intended to prevent recursion but it also prevents repetition.
Comment #5
traviscarden commentedClarifying in the title that this is not an argument for allowing greater recursion but rather a report that repetition is misidentified as recursion. To be precise, the static counter @briangeorge highlights, in
\Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsEntityFormatter::viewElements(), assumes it will only be incremented when called recursively, but it appears to increment every time the entity is rendered within the same PHP process, whether recursively called or not.Comment #6
miro_dietikerIt seems this is not a paragraphs / ERR specific problem only.
We ran into this with a entity reference field pointing to media in Search API. Since the same example media was placed many times on the same page, it was rendered multiple times. This caused recursion detection and killed indexing.
Comment #7
maacl commentedI am testing the patch from https://www.drupal.org/project/drupal/issues/2828364#comment-12538290
But it only fights the symptom.
Use Case: Parapgraphs and Media Entity, lots of nesting.
These seem related:
Comment #8
ious commentedHi all,
I got the same issue not being able to render the same reference more than 20 times.
I have several nodes including a reference to the same node A including several medias.
Every Cron I got an entity.ERROR for each media linked to node A:
Example of one error message:
entity.ERROR: Recursive rendering detected when rendering entity media: 248, using the field_media field on the slide_media bundle. Aborting rendering. {"%entity_type":"media","%entity_id":"248","%field_name":"field_media","%bundle_name":"slide_media"}
Seems to be only "hacky" solutions available for something that seems a large blocker.
I posted too on #2940605: Can only intentionally re-render an entity with references 20 times.
Cheers,
Comment #9
wim leersThis seems to be caused by the design choices in #2073753: Fix and add tests for the recursive rendering protection of the 'Rendered entity' formatter. #2940605: Can only intentionally re-render an entity with references 20 times already pointed this out too.
If I were the maintainer of this module, I'd mark this blocked on #2940605: Can only intentionally re-render an entity with references 20 times, since that's the root cause, and this module follows core's example (and hence inherits the root cause).
Comment #10
berdirYeah, that's the same problem, but we don't really need to postpone, as we will need to reimplement whatever core does here anyway, and we could do that also before core does.
The problem isn't the limit, the problem is that we are unable to detect when a rendering happened, with delayed rendering and render cache, so we can decrease the counter again. maybe we could add some kind of callback, but it would need to be called even in case of a render cache it.
Comment #11
mlncn commentedI think i'm seeing this same thing bubble up into Search API Solr indexing:
"Recursive rendering detected when rendering entity node: 1606, using the field_findit_locations field on the node:findit_program 3127 entity. Aborting rendering."
The first mentioned entity is a location node, which contains no references back to anything— but is re-used, shared among multiple program nodes.
Is the 20 entity limit from core applicable in this case also? If so I suppose that batch sizes of 20 (and more frequent cron) would be enough to work around this. But if the second duplicate entity (referenced by separate nodes, note) triggers it, i don't think a batch size of one is feasible!
Comment #12
miro_dietikerPromoting a bit for awareness as this is an unexpected architectural / design limitation causing some real pain that is hard to mitigate...
Comment #13
kiseleva.t commentedI also faced with that issue on search indexing.
I made a patch for entity_reference_revisions (attached one) similar to https://www.drupal.org/project/drupal/issues/2940605#comment-14033526 to solve this issue (both patches should be applied to have it work, because the core one provides the required logic in EntityReferenceFormatterBase)
Comment #14
alexdoma commentedUpdate previous patch due to php 8.1 Deprecated function: substr_count()
Deprecated function: substr_count(): Passing null to parameter #1 ($haystack) of type string is deprecated in Drupal\entity_reference_revisions\Plugin\Field\FieldFormatter\EntityReferenceRevisionsEntityFormatter->viewElements() (line 144 of /var/www/html/web/modules/contrib/entity_reference_revisions/src/Plugin/Field/FieldFormatter/EntityReferenceRevisionsEntityFormatter.php)Comment #15
socialnicheguru commentedis this a duplicate of #2568187: Improve EntityReferenceRevisionsItem::generateSampleValue to be recursion-safe and devel_generate compatible
Comment #16
berdirNo
Comment #17
benstallings commentedClaude Code says:
Assessment: Reject this patch. It's broken and obsolete.
Critical bug: _render_path is never set
The patch checks $entity->_render_path but nothing in the patch ever populates it. The value will always be NULL, so substr_count('' , $recursive_render_id) will always be 0, and the recursion protection will never trigger. This effectively removes all recursion protection.
The right approach: remove the formatter-level protection entirely
As of Drupal 11.4 (core issue #3316878), recursion protection has been moved out of the formatter and into EntityViewBuilder itself, via #pre_render / #post_render callbacks (setRecursiveRenderProtection / unsetRecursiveRenderProtection). Core's own EntityReferenceEntityFormatter::viewElements() no longer contains any recursion tracking — it just calls $view_builder->view() and the view builder handles it.
Since the ERR formatter already calls \Drupal::entityTypeManager()->getViewBuilder(...)->view(...), the core-level protection applies automatically. The correct fix would be to simply remove the static $depth tracking and $depth = 0 reset from the ERR formatter, matching what core did. No replacement logic needed.
Additional problems with the patch
- Dynamic property: $entity->_render_path would be a dynamic property on a ContentEntityBase subclass, triggering deprecation notices in PHP 8.2+ (the module already fixed this class of issue in #3544409).
- substr_count is fragile: Searching for "field:1" in a path string would match "field:11" or "field:100", causing false positives.
- The RECURSIVE_RENDER_LIMIT constant and improved error message are good ideas, but moot if the whole mechanism should be removed.