Problem/Motivation

modules/charts_chartjs/charts_chartjs.libraries.yml (5.1.x and 5.2.x) defines:

chartjs:
  version: 1.x
  js:
    js/charts_chartjs.js: { weight: -1, attributes: { defer: true } }
  dependencies:
    - charts/global
    - charts_chartjs/chartjs

Drupal's AssetResolver::getJsAssets() sorts JavaScript by weight and only preserves dependency order between files of equal weight (it adds a tiny insertion-order fraction to the weight). Because js/charts_chartjs.js has an explicit weight: -1 while charts/global (js/charts.js) keeps the default weight 0, charts_chartjs.js is emitted before charts.js, i.e. before its own dependency. Measured on Drupal 11.4 with charts 5.2.2:

modules/contrib/charts/modules/charts_chartjs/js/charts_chartjs.js  weight=-0.9997
modules/contrib/charts/js/charts.js                                 weight= 0.00013

On a plain page load this is masked: charts_chartjs.js is defer and charts.js is not, so charts.js still executes first. But when the chart sits inside a BigPipe placeholder (e.g. a Views chart block placed with Layout Builder, or any block with a lazy builder) or arrives in an AJAX response, both files are added dynamically by loadjs in document order and defer no longer applies. charts_chartjs.js then executes first and registers Drupal.behaviors.chartsChartjs. If any Drupal.attachBehaviors() runs between the execution of the two files (another BigPipe placeholder being replaced does exactly that), the behavior runs while Drupal.Charts does not exist yet:

Uncaught TypeError: Cannot read properties of undefined (reading 'Contents')
    at Object.attach (modules/contrib/charts/modules/charts_chartjs/js/charts_chartjs.js:21)
    at Drupal.attachBehaviors (core/misc/drupal.js:162)
    at core/modules/big_pipe/js/big_pipe.js:137

The new Drupal.Charts.Contents() call sits before the once() guard, so the error is thrown even when there is nothing for that attach round to do. The error is intermittent (it depends on the order in which placeholders arrive) and the chart usually still renders on a later attach round, so the visible symptom is "random console errors on chart pages".

Steps to reproduce

  1. Drupal 10.3+/11 with BigPipe enabled, charts + charts_chartjs 5.2.x.
  2. Place a Views chart block (Chart.js) on a page via Layout Builder together with at least one other block that is BigPipe-placeholdered (anything with a #lazy_builder, e.g. a per-user block). Log in so BigPipe streams.
  3. Load the page a few times with the console open: intermittently the TypeError above appears. Confirm the asset order with \Drupal::service('asset.resolver')->getJsAssets() for the libraries charts/global and charts_chartjs/chartjs.

Proposed resolution

Remove the explicit weight so the file simply follows its dependency:

    js/charts_chartjs.js: { attributes: { defer: true } }

Alternatively, if the -1 is intentional (to run before other libraries at weight 0), give charts/global's js/charts.js a lower weight (e.g. -2) so it still precedes every backend script. Either way Drupal.Charts is then guaranteed to exist when chartsChartjs.attach runs.

Optionally harden charts_chartjs.js as well: move new Drupal.Charts.Contents() inside the once() loop, or bail out early if Drupal.Charts is undefined, so a stray early attach round cannot throw.

Workaround for sites

/**
 * Implements hook_library_info_alter().
 */
function MYMODULE_library_info_alter(array &$libraries, $extension): void {
  if ($extension === 'charts_chartjs' && isset($libraries['chartjs']['js']['js/charts_chartjs.js']['weight'])) {
    unset($libraries['chartjs']['js']['js/charts_chartjs.js']['weight']);
  }
}

Verified on our site: with the weight removed the order becomes charts.js (0.00013) before charts_chartjs.js (0.0003) and the error no longer occurs on pages with 7–9 BigPipe-loaded charts.

Remaining tasks

Review the MR (one-line change in charts_chartjs.libraries.yml).

Issue fork charts-3620588

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

magnolia61 created an issue. See original summary.

magnolia61’s picture

Status: Active » Needs review

MR !231 opened against 5.2.x: https://git.drupalcode.org/project/charts/-/merge_requests/231

One-line change: drop the explicit weight: -1 from js/charts_chartjs.js in charts_chartjs.libraries.yml so it follows its dependency charts/global. Measured order after the change: charts.js 0.00013 before charts_chartjs.js 0.0003; the reading 'Contents' TypeError no longer occurs on our BigPipe pages with 7–9 charts.

andileco made their first commit to this issue’s fork.

andileco changed the visibility of the branch 3620588-charts-chartjs-weight to hidden.

  • andileco committed f5678d37 on 5.2.x
    fix: #3620588 charts_chartjs.js has weight -1 and loads before its...
andileco’s picture

Status: Needs review » Fixed

Thanks for your contribution, @magnolia61. Your MR had a lot of extra code, so I just took your one line and made a new MR.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.