Summary

AssertionError: assert(!array_diff(array_keys($modules_by_identifier), $identifiers)) in assert() (line 534 of /app/docroot/core/lib/Drupal/Core/Extension/ModuleHandler.php).

Upgraded the Drupal from 11.1.8 to 11.3.0, updb executed successfully and the status report is also showing 11.3.0.

The issue happened is when I try to load a node in front end, it is saying "The website encountered an unexpected error. Try again later.". We can see the above mentioned error in the dblog.

The issue is coming from:
Lightning Workflow
Specifically this function:
function lightning_workflow_module_implements_alter(array &$implementations, $hook) {
if ($hook == 'node_view_alter') {
//unset($implementations['quickedit']);
}
}

In Drupal 11.3, core tightened validation inside:
ModuleHandler::getCombinedListeners()
Now Drupal asserts that:
assert(!array_diff(array_keys($modules_by_identifier), $identifiers));
So when this module does:
unset($implementations['quickedit']);
it removes an implementation that core still expects to exist.
Before 11.3 → Drupal tolerated this.
After 11.3 → Assertion error.

Steps to reproduce

Upgrade Drupal to 11.3.0.
View any node will throw error.

Proposed resolution

Update the hook like this

function lightning_workflow_module_implements_alter(array &$implementations, $hook) {
if ($hook === 'node_view_alter') {
if (isset($implementations['quickedit'])) {
// Reorder instead of removing (Drupal 11.3 safe)
$quickedit = $implementations['quickedit'];
unset($implementations['quickedit']);
$implementations['quickedit'] = $quickedit;
}
}
}

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

fredy davy stalin created an issue. See original summary.

fredy davy stalin changed the visibility of the branch 3576628-assertion-error-triggering to hidden.

fredy davy stalin changed the visibility of the branch 3576628-assertion-error-triggering to active.

fredy davy stalin’s picture

StatusFileSize
new821 bytes

I have created a patch that will resolve the error

fredy davy stalin’s picture

Status: Active » Needs review

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

velmir_taky’s picture

Root cause: lightning_workflow_module_implements_alter() calls unset($implementations['quickedit']) for node_view_alter hook. In Drupal 11.3+, ModuleHandler::getCombinedListeners() asserts that all keys in $modules_by_identifier must exist in $identifiers (line 548). Removing a module via module_implements_alter breaks this invariant because the module's identifiers remain in $modules_by_identifier but are excluded from the reordered $identifiers list.

Why #4 is insufficient: Reordering (unset + re-add) still keeps quickedit in implementations, but on Drupal 11 where quickedit doesn't exist, it's a no-op anyway. On Drupal 9/10 where quickedit exists, reordering to the end breaks the wrapping pattern — quickedit_entity_view_alter() runs both from its own implementation AND manually from lightning_workflow_entity_view_alter() (line 211).

This MR:
- module_implements_alter() => no-op (Quick Edit was removed from core in 10.0, wrapping is dead code)
- Added #[LegacyModuleImplementsAlter] attribute (required since 11.2, see https://www.drupal.org/node/3496788)
- theme_registry_alter() => guarded with moduleExists('quickedit') early return
- RouteSubscriber::isViewing() => explicit nullable type ?RouteMatchInterface (PHP 8.4 deprecation)
- core_version_requirement => ^9.0.6 || ^10 || ^11
- Added ModuleImplementsAlterTest kernel test (2 tests, 3 assertions)

carlos romero made their first commit to this issue’s fork.