Error when setting batch on user insert

Created on 2 May 2025, 14 days ago

Problem/Motivation

When upgrading this module from 2.1.1 to 2.1.2 (on Drupal 10.4.6), I can no longer create users without getting the following error:

The website encountered an unexpected error. Try again later.

LogicException: The database connection is not serializable. This probably means you are serializing an object that has an indirect reference to the database connection. Adjust your code so that is not necessary. Alternatively, look at DependencySerializationTrait as a temporary solution. in Drupal\Core\Database\Connection->__sleep() (line 1920 of core/lib/Drupal/Core/Database/Connection.php).

The stack trace that followed showed batch functions, which gave me the clue about where the problem is occurring. I am adding a batch on user insert (this is not new, it's been working for years); if I remove the batch, the error does not occur.

Steps to reproduce

Set a batch on user insert. A simple example (which doesn't do anything) is provided below; and even though I am passing user here (because my actual use case requires it), the error occurs even if user is not passed to the batch process.

use Drupal\user\UserInterface;

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function my_module_user_insert(UserInterface $user) {
  // Testing for genpass issue.
  $ops = [];
  $ops[] = ['_my_module_batch_test', [$user], []];

  $batch = [
    'title' => t('Batch test on user insert'),
    'operations' => $ops,
    'init_message' => t('Testing.'),
    'progress_message' => t('Step @current of @total'),
    'error_message' => t('An error occurred during processing.'),
    'finished' => '_my_module_batch_test_finished',
  ];

  batch_set($batch);
}

/**
 * Batch operation.
 *
 * @param \Drupal\user\UserInterface $user
 *   The user entity.
 * @param array|object $context
 *   Context passed by reference through the batch process.
 */
function _my_module_batch_test(UserInterface $user, &$context) {
  $context['results']['username'] = $user->getDisplayName();
  $context['message'] = t('Testing...');
  $context['finished'] = 1;
}

/**
 * Batch finished callback.
 *
 * @param bool $success
 *   Whether the batch was successful.
 * @param array $results
 *   The processed results from the batch.
 * @param array $operations
 *   In case of error, the operations that remained unprocessed.
 */
function _my_module_batch_test_finished($success, array $results, array $operations) {
  $messenger = \Drupal::messenger();
  if ($success) {
    $messenger->addStatus(t('Batch test on user insert complete for @user.', [
      '@user' => $results['username'],
    ]));
  }
  else {
    $messenger->addError(t('Error testing batch on user insert.'));
  }
}

Proposed resolution

I took a quick look at the changes introduced in 2.1.2, and although I suspect it has to do with the changes from 📌 Migrate to OO hooks Active , unfortunately I'm not sure how to resolve this.

Remaining tasks

  • ✅ File an issue
  • ➖ Addition/Change/Update/Fix
  • ➖ Testing to ensure no regression
  • ➖ Automated unit testing coverage
  • ➖ Automated functional testing coverage
  • ➖ UX/UI designer responsibilities
  • ➖ Readability
  • ➖ Accessibility
  • ➖ Performance
  • ➖ Security
  • ➖ Documentation
  • ➖ Code review by maintainers
  • ➖ Full testing and approval
  • ➖ Credit contributors
  • ➖ Review with the product owner
  • ➖ Release notes snippet
  • ❌ Release

User interface changes

  • N/A

API changes

  • N/A

Data model changes

  • N/A

Release notes snippet

  • N/A
🐛 Bug report
Status

Active

Version

2.1

Component

Code

Created by

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

Merge Requests

Comments & Activities

  • Issue created by @bgustafson
  • First commit to issue fork.
  • 🇦🇺Australia elc

    Thanks for the terrific bug report!

    I suspect it will be one of the new Hook namespace services is being included in one of the services used in the batch, all of which get serialized between batch steps.

    With the code you've provided, we can make a test to reproduce the issue and hunt down which of them is causing the issue.

  • Pipeline finished with Success
    13 days ago
    Total: 383s
    #488121
  • Pipeline finished with Success
    13 days ago
    Total: 269s
    #488124
  • 🇦🇺Australia elc

    Does this fix the issue?

    I believe it's the specific cache being injected. I've used the DependencySerializationTrait in Hook/FormAlter for now, but CacheFactoryInerface could be injected instead to prevent the need.

  • This works well for me, thanks!

    • elc committed 663a4356 on 2.1.x
      [#3522473] Use DependencySerializationTrait in Hook/FormAlter service.
      
  • 🇦🇺Australia elc

    Having pulled every service injection, I've found there are at least 2 that are tripping up serialization. The DependencySerializationTrait method will stay unless someone can figure out which services can be bypassed to avoid it. It seems fairly harmless as it's only used when an altered form is used to trigger a batch.

Production build 0.71.5 2024