Repository navigation
Cover isDark can cause recursive loop with Featured Image in a Query Loop #74976
Copy link
Copy link
Open
Labels
[Block] CoverAffects the Cover Block - used to display content laid over a background imageAffects the Cover Block - used to display content laid over a background image[Status] In ProgressTracking issues with work in progressTracking issues with work in progress[Type] BugAn existing feature does not function as intendedAn existing feature does not function as intended
Description
Description
This is in regard to the core/cover block's isDark check here:
gutenberg/packages/block-library/src/cover/edit/index.js
Lines 146 to 177 in 2fd341f
| // User can change the featured image outside of the block, but we still | |
| // need to update the block when that happens. This effect should only | |
| // run when the featured image changes in that case. All other cases are | |
| // handled in their respective callbacks. | |
| useEffect( () => { | |
| ( async () => { | |
| if ( ! useFeaturedImage ) { | |
| return; | |
| } | |
| const averageBackgroundColor = await getMediaColor( mediaUrl ); | |
| let newOverlayColor = overlayColor.color; | |
| if ( ! isUserOverlayColor ) { | |
| newOverlayColor = averageBackgroundColor; | |
| __unstableMarkNextChangeAsNotPersistent(); | |
| setOverlayColor( newOverlayColor ); | |
| } | |
| const newIsDark = compositeIsDark( | |
| dimRatio, | |
| newOverlayColor, | |
| averageBackgroundColor | |
| ); | |
| __unstableMarkNextChangeAsNotPersistent(); | |
| setAttributes( { | |
| isDark: newIsDark, | |
| isUserOverlayColor: isUserOverlayColor || false, | |
| } ); | |
| } )(); | |
| // Update the block only when the featured image changes. | |
| }, [ mediaUrl ] ); |
When set inside a template part as part of a core/template-part block, which itself is used in a core/query loop, it can cause endless looping of isDark being set between false and true. This happens when there are at least two different images where one evaluates to true and the other false. Since the origin template is the same, this causes the isDark attribute to bounce between the two values.
Commenting out the setAttributes() call in the above function stops the endless looping.
Step-by-step reproduction instructions
- Install WordPress.
- Set Twenty Twenty-Five as the theme.
- Edit the default Hello world! post.
- Upload and set the following image as the featured image:

- Create a new post, with whatever title and content. Set the following as its featured image:

- Create a new file
/wp-content/themes/twentytwentyfive/parts/teaser.html:<!-- wp:cover {"useFeaturedImage":true,"dimRatio":30,"isUserOverlayColor":true,"isDark":false,"sizeSlug":"large","layout":{"type":"default"}} --> <div class="wp-block-cover is-light"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-30 has-background-dim"></span><div class="wp-block-cover__inner-container"> </div></div> <!-- /wp:cover -->
- Edit Blog Index template (go to
/wp-admin/site-editor.php?canvas=edit&p=%2Fwp_template%2Ftwentytwentyfive%2F%2Fhome) and paste the following into the template in Code Editor mode:<!-- wp:query {"queryId":1,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true,"taxQuery":null,"parents":[]},"align":"full","layout":{"type":"default"}} --> <div class="wp-block-query alignfull"> <!-- wp:post-template {"align":"full","layout":{"type":"default"}} --> <!-- wp:template-part {"slug":"teaser","theme":"twentytwentyfive"} /--> <!-- /wp:post-template --> </div> <!-- /wp:query -->
- Exit Code Editor and see the constant replacement behavior of the blocks.
Screenshots, screen recording, code snippet
Video.Project.16.mp4
Environment info
- WordPress 6.9, Twenty Twenty-Five
- Google Chrome 143.0.7499.193 (64 bit)
- Desktop Windows 11
Please confirm that you have searched existing issues in the repo.
- Yes
Please confirm that you have tested with all plugins deactivated except Gutenberg.
- Yes
Please confirm which theme type you used for testing.
- Block
- Classic
- Hybrid (e.g. classic with theme.json)
- Not sure
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
[Block] CoverAffects the Cover Block - used to display content laid over a background imageAffects the Cover Block - used to display content laid over a background image[Status] In ProgressTracking issues with work in progressTracking issues with work in progress[Type] BugAn existing feature does not function as intendedAn existing feature does not function as intended
Activity
Swanand01 commentedon Feb 5, 2026
Hi @wongjn, thanks for reporting this! I was able to reproduce this bug on trunk.
As a fix, we could use local state for
isDarkwhen using featured images instead. This prevents multiple post instances in Query Loops from conflicting over the shared template'sisDarkvalue.The infinite loop stops because each post now maintains its own computed
isDarkvalue in memory rather than fighting over the template.talldan commentedon Mar 16, 2026
Is it the same bug as Cover Block: flickering in site editor page view when used within a synced pattern?
It looks like it to me.
If so then it might be worth figuring out why the fix regressed.
Swanand01 commentedon Mar 17, 2026
I think PR #53253 fixed flickering in synced patterns by moving
isDarkcalculations from useEffects to event handlers, but kept one useEffect for featured images since those changes happen outside the component.The featured image useEffect worked fine for synced patterns but causes the same flickering issue in Query Loops because multiple post instances share the same template.