Skip to content

Cover isDark can cause recursive loop with Featured Image in a Query Loop #74976

Open

Description

@wongjn

Description

This is in regard to the core/cover block's isDark check here:

// 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

  1. Install WordPress.
  2. Set Twenty Twenty-Five as the theme.
  3. Edit the default Hello world! post.
  4. Upload and set the following image as the featured image:
    Image
  5. Create a new post, with whatever title and content. Set the following as its featured image:
    Image
  6. 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 -->
  7. 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 -->
  8. 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

Activity

  1. added
    [Type] BugAn existing feature does not function as intended
    on Jan 27, 2026
  2. added
    [Block] CoverAffects the Cover Block - used to display content laid over a background image
    on Jan 28, 2026
  3. Swanand01 commented on Feb 5, 2026

    @Swanand01
    Contributor

    Hi @wongjn, thanks for reporting this! I was able to reproduce this bug on trunk.

    As a fix, we could use local state for isDark when using featured images instead. This prevents multiple post instances in Query Loops from conflicting over the shared template's isDark value.

    The infinite loop stops because each post now maintains its own computed isDark value in memory rather than fighting over the template.

  4. talldan commented on Mar 16, 2026

    @talldan
    Contributor

    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.

  5. Swanand01 commented on Mar 17, 2026

    @Swanand01
    Contributor

    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.

    I think PR #53253 fixed flickering in synced patterns by moving isDark calculations 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

[Block] CoverAffects the Cover Block - used to display content laid over a background image[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions