TypeError during drush deploy: Argument #2 ($module) must be of type string, null given

Created on 27 August 2025, 6 days ago

While trying to upgrade to Drupal 11, during drush deploy, or drush updb i get the following stacktrace

   [warning] Undefined array key "rebuild" ModuleHandler.php:356                                                                                                     
   [warning] Trying to access array offset on null ModuleHandler.php:356                                                                                             
   [error]  TypeError: Drupal\Core\Extension\ModuleHandler::Drupal\Core\Extension\{closure}(): Argument #2 ($module) must be of type string, null given, called in   
  /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php on line 357 in Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}() (  
  line 403 of /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php) #0 /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.p  
  hp(357): Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}()                                                                                    
  #1 /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php(403): Drupal\Core\Extension\ModuleHandler->invokeAllWith()                            
  #2 /var/www/html/app/public/core/includes/common.inc(465): Drupal\Core\Extension\ModuleHandler->invokeAll()                                                        
  #3 /var/www/html/app/vendor/drush/drush/src/Commands/core/UpdateDBCommands.php(96): drupal_flush_all_caches()                                                      
  #4 [internal function]: Drush\Commands\core\UpdateDBCommands->updatedb()                                                                                           
  #5 /var/www/html/app/vendor/consolidation/annotated-command/src/CommandProcessor.php(276): call_user_func_array()                                                  
  #6 /var/www/html/app/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback()   
  #7 /var/www/html/app/vendor/consolidation/annotated-command/src/CommandProcessor.php(175): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter()  
  #8 /var/www/html/app/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(387): Consolidation\AnnotatedCommand\CommandProcessor->process()              
  #9 /var/www/html/app/vendor/symfony/console/Command/Command.php(318): Consolidation\AnnotatedCommand\AnnotatedCommand->execute()                                   
  #10 /var/www/html/app/vendor/symfony/console/Application.php(1092): Symfony\Component\Console\Command\Command->run()                                               
  #11 /var/www/html/app/vendor/symfony/console/Application.php(341): Symfony\Component\Console\Application->doRunCommand()                                           
  #12 /var/www/html/app/vendor/symfony/console/Application.php(192): Symfony\Component\Console\Application->doRun()                                                  
  #13 /var/www/html/app/vendor/drush/drush/src/Runtime/Runtime.php(110): Symfony\Component\Console\Application->run()                                                
  #14 /var/www/html/app/vendor/drush/drush/src/Runtime/Runtime.php(40): Drush\Runtime\Runtime->doRun()                                                               
  #15 /var/www/html/app/vendor/drush/drush/drush.php(140): Drush\Runtime\Runtime->run()                                                                              
  #16 /var/www/html/app/vendor/bin/drush.php(119): include('...')                                                                                                    
  #17 {main}.                                                                                                                                                        
  TypeError: Drupal\Core\Extension\ModuleHandler::Drupal\Core\Extension\{closure}(): Argument #2 ($module) must be of type string, null given, called in /var/www/h  
  tml/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php on line 357 in /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php on line   
  403 #0 /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php(357): Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}()      
  #1 /var/www/html/app/public/core/lib/Drupal/Core/Extension/ModuleHandler.php(403): Drupal\Core\Extension\ModuleHandler->invokeAllWith()                            
  #2 /var/www/html/app/public/core/includes/common.inc(465): Drupal\Core\Extension\ModuleHandler->invokeAll()                                                        
  #3 /var/www/html/app/vendor/drush/drush/src/Commands/core/UpdateDBCommands.php(96): drupal_flush_all_caches()                                                      
  #4 [internal function]: Drush\Commands\core\UpdateDBCommands->updatedb()                                                                                           
  #5 /var/www/html/app/vendor/consolidation/annotated-command/src/CommandProcessor.php(276): call_user_func_array()                                                  
  #6 /var/www/html/app/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback()   
  #7 /var/www/html/app/vendor/consolidation/annotated-command/src/CommandProcessor.php(175): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter()  
  #8 /var/www/html/app/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(387): Consolidation\AnnotatedCommand\CommandProcessor->process()              
  #9 /var/www/html/app/vendor/symfony/console/Command/Command.php(318): Consolidation\AnnotatedCommand\AnnotatedCommand->execute()                                   
  #10 /var/www/html/app/vendor/symfony/console/Application.php(1092): Symfony\Component\Console\Command\Command->run()                                               
  #11 /var/www/html/app/vendor/symfony/console/Application.php(341): Symfony\Component\Console\Application->doRunCommand()                                           
  #12 /var/www/html/app/vendor/symfony/console/Application.php(192): Symfony\Component\Console\Application->doRun()                                                  
  #13 /var/www/html/app/vendor/drush/drush/src/Runtime/Runtime.php(110): Symfony\Component\Console\Application->run()                                                
  #14 /var/www/html/app/vendor/drush/drush/src/Runtime/Runtime.php(40): Drush\Runtime\Runtime->doRun()                                                               
  #15 /var/www/html/app/vendor/drush/drush/drush.php(140): Drush\Runtime\Runtime->run()                                                                              
  #16 /var/www/html/app/vendor/bin/drush.php(119): include('...')                                                                                                    
  #17 {main}                                                                                                                                                         
   [warning] Drush command terminated abnormally.                                                                                                                    

I did some digging and found the cause.

  public function invokeAllWith(string $hook, callable $callback): void {
    foreach ($this->getFlatHookListeners($hook) as $index => $listener) {
      $module = $this->modulesByHook[$hook][$index];
      $callback($listener, $module);
    }
  }

this is the function of the moduleHandler in which the error is thrown. $this->modulesByHook is an Array containing the hooks, for example rebuild and the modules for which to call them ($index)

After calling the hook_rebuild for simple_menu_icons, $this->modulesByHook is empty, causing the next iteration after to fail with the specified error.

Why is that?
Further analysis pointed me to the theme. The function called in simple_menu_icons_rebuild contains this line

    $css = \Drupal::service('renderer')->renderInIsolation($menu_css);

this eventually leads to the ThemeManager which leads to this line of its render function

    $theme_registry = $this->themeRegistry->getRuntime();

lastly this may call new ThemeRegistry(...) which contains $this->storage = $this->initializeRegistry(); which contains

    $this->completeRegistry = \Drupal::service('theme.registry')->get();

this is the line, which empties $this->modulesByHook all the way back at the ModuleHandler, causing the error.

Changing the hook to simple_menu_icons_cache_flush fixes the error for me, but i do not know if this is best practice, or if it keeps full functionality

🐛 Bug report
Status

Active

Version

3.1

Component

Code

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

Comments & Activities

  • Issue created by @Johannes.Heinzerling
  • 🇵🇱Poland mahyarss

    I've identified the root cause and have a working solution.
    Problem Analysis:
    The issue occurs because simple_menu_icons_rebuild() calls \Drupal::service('renderer')->renderInIsolation() which triggers theme registry initialization during the rebuild process. This causes $modulesByHook array in ModuleHandler to be cleared while still being iterated over, resulting in the TypeError.
    Solution:
    Move CSS generation from hook_rebuild() to hook_cache_flush(). This is semantically correct since CSS generation is a cache operation, not a data structure rebuild.
    Testing:
    Tested with Drupal 11.0.x and confirmed:

    • Multiple drush cr executions complete without errors
    • CSS generation works correctly
    • Menu icons display properly

    Patch attached: simple_menu_icons-d11_hook_rebuild_fix-3543309-2.patch

    The patch includes:

    1. Replace hook_rebuild() with hook_cache_flush()
    2. Add simple_menu_icons_generate_css_content() function to avoid renderInIsolation() during rebuild
    3. Add error handling and validation
    4. Update hook documentation

    Steps to reproduce the fix:

    # Apply patch
    patch -p1 < simple_menu_icons-d11_hook_rebuild_fix-3543309-2.patch
    
    # Clear cache multiple times to verify
    drush cr && drush cr && drush cr
    
    # Verify functionality
    drush ev "simple_menu_icons_cache_flush();"

    This change maintains backward compatibility with Drupal 10 while fixing the Drupal 11 issue.

Production build 0.71.5 2024