[regression since 11.2] Uncaught TypeError: Cannot set properties of undefined (setting 'textContent') at ContextualModelView.render (contextual.js?v=11.2.2:356:29)

Created on 9 July 2025, about 2 months ago

Problem/Motivation

It looks like https://www.drupal.org/project/drupal/issues/3203920 📌 Replace Contextual Links BackboneJS usage with VanillaJS equivalent Needs work caused a regression in specific scenarios.
After updating from D10.4 to 11.2, I see the following JS error:

Uncaught TypeError: Cannot set properties of undefined (setting 'textContent')
    at ContextualModelView.render (contextual.js?v=11.2.2:356:29)
    at new ContextualModelView (contextual.js?v=11.2.2:331:14)
    at initContextual (contextual.js?v=11.2.2:113:33)
    at contextual.js?v=11.2.2:167:13

This seems to happen when some HTML that contains contextual links are being relocated in JS.
On my project, it happens with the mmenu JS which clones a ul (which contains blocks inside) to the bottom right before the closing body tag.
I did manage to reproduce with olivero, given

Steps to reproduce

- Install standard profile on 11.x branch
- Add the following behavior, anywhere

Drupal.behaviors.contextual_bug = {
  attach(context) {
    once('bugbug', '#block-olivero-views-block-who-s-online-who-s-online-block .block__content', context).forEach((element) => {
      // Move the who's online block content at the bottom, before body closing tag.
      const clone = element.cloneNode(true);
      document.body.appendChild(clone);
      element.remove();
    });
  }
}

(I place it in core/modules/contextual/js/contextual.js:537 at the bottom, but in the IIFE)
- Login as uid1, add the who's online block in the content region
- Clear cache, hit the homepage (still logged in!)
>>> The JS error is thrown

Proposed resolution

TBD

Remaining tasks

TODO

User interface changes

N/A

Introduced terminology

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

🐛 Bug report
Status

Active

Version

11.2 🔥

Component

contextual.module

Created by

🇧🇪Belgium herved

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @herved
  • 🇧🇪Belgium herved

    So far I see the code at core/modules/contextual/js/contextual.js:167 is attempting to get data-contextual-id elements that are not guaranteed to be there if these were relocated.

    window.setTimeout(() => {
      initContextual(
        $context
          .find(`[data-contextual-id="${contextualID.id}"]:empty`)
          .eq(0),
        html,
      );
    });
    

    But this line hasn't changed in #3203920 so probably there is something more at play there.

  • Pipeline finished with Failed
    about 2 months ago
    Total: 263s
    #543784
  • 🇧🇪Belgium herved

    Static patch for composer

  • Pipeline finished with Failed
    about 2 months ago
    Total: 683s
    #543794
  • 🇨🇳China murphyw

    My Drupal version is 11.2.0

  • 🇮🇳India himanshu raj Noida

    I was able to reproduce the issue by following the same steps as mentioned above:

    1. Added the below JS snippet manually in the contextual.js file to simulate block movement:

    Drupal.behaviors.contextual_bug = {
      attach(context) {
        once('contextual_bug', '#block-olivero-views-block-who-s-online-who-s-online-block .block__content', context).forEach((element) => {
          // Move the who's online block content at the bottom, before body closing tag, replicating mmenu.
          const clone = element.cloneNode(true);
          document.body.appendChild(clone);
          element.remove();
        });
      }
    }

    2. Placed the Who's online block in the Content region.
    3. Reloaded the page.
    At this point, I saw the following error in the browser console:

    Uncaught TypeError: Cannot set properties of undefined (setting 'textContent')

    Then I applied the patch from #10 and run composer install.
    After applying the patch:

    The error disappeared from the console.

    ###Patch / MR tested
    Applied patch from #10

    ###Results:

    JS console error disappeared after applying the patch.

    ### Environment
    Drupal 11.2.x, PHP 8.3, MySQL 8.0, DDEV 1.25 (Docker + WSL2).

  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    There are multiple places we call initContextual, we've updated one of those calls to check the element exists, but not the other.
    But we've also updated the logic inside initContextual - I don't think we need both.
    I'm inclined to make it check it from the outside rather than inside

    Let's do that - thanks!

Production build 0.71.5 2024