Drupal comes with a default contact form on each site we install. And while we already have the webforms and recaptcha module installed, some of our site owners still use the default contact form found in /admin/structure/contact.

I need to remove them because when they are enabled, the site is prone to spam attacks. I've had a few instances where some of the sites had form submissions with PDF file uploads of inappropriate content. So you see how this is a security risk for our organization.

I removed that contact form in my local site by disabling the following modules in this order:

  • contact form
  • contact storage
  • contact

But I need to do this for all our sites now, so I wrote the following in my hook_update_n() function:

function my_profile_update_8011() {
    $config = \Drupal::configFactory();
    $moduleHandler = \Drupal::service('module_handler');

    if($moduleHandler->moduleExists('lightning_contact_form')) {
    if($moduleHandler->moduleExists('contact_storage')) {
    if($moduleHandler->moduleExists('contact')) {


When I deployed this update to our dev environment, it would work on most of the sites, but fail on the rest. They all have this same error message:

The error output from the server was: >  [notice] Update started: my_profile_update_8011
>  [error]  SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause': SELECT 1 AS expression
> {contact_message} t
> LIMIT 1 OFFSET 0; Array
> (
> )
>  [error]  Update failed: my_profile_update_8011
 [error]  Update aborted by: my_profile_update_8011
 [error]  Finished performing updates.

All our sites share the same codebase, so I don't know where my update hook went wrong. Is there a better way of disabling these modules?

thanks, Kevin

  • I recommend using configuration management for a better way to disable modules in upstream environments. It's a bit more complicated with multi-site, but it can be done using Configuration Split: drupal.org/project/config_split. Commented May 2, 2021 at 20:22

1 Answer 1


You may be able to use this (untested) approach in your hook_update_N() implementation:

function my_profile_update_8011() {
  $config = \Drupal::configFactory();
  $moduleHandler = \Drupal::service('module_handler');

  $mods_removable = [

  // Read the configuration.
  $module_data = $config->getEditable('core.extension')->get('module');

  foreach ($mods_removable as $module) {
    if($moduleHandler->moduleExists($module)) {
      // Unset the modules you do not need.

  // Write the configuration.
  $config->getEditable('core.extension')->set('module', $module_data)->save();

See this answer for additional info.

  • 1
    Thanks for your input! However, when I tried it, I'm getting a syntax error on the following line unset($module_data[$module]); The error message was: "The message from the server was: ParseError: syntax error, unexpected 'unset' (T_UNSET) in module_load_include()"
    – kcsting
    Commented May 3, 2021 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.