Problem/Motivation

This issue was originally brought into focus when PHP 8.1 was introduced.

Error message when enabling modules:

Deprecated function: mb_strtolower(): Passing null to parameter #1 ($string) of type string is deprecated in Drupal\Core\Config\Entity\Query\Condition->compile() (line 39 of core/lib/Drupal/Core/Config/Entity/Query/Condition.php).
Drupal\Core\Config\Entity\Query\Condition->compile(Array) (Line: 85)
Drupal\Core\Config\Entity\Query\Query->execute() (Line: 301)
Drupal\Core\Config\Entity\ConfigEntityBase->preSave(Object) (Line: 124)
Drupal\language\Entity\ConfigurableLanguage->preSave(Object) (Line: 562)
Drupal\Core\Entity\EntityStorageBase->doPreSave(Object) (Line: 517)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 253)
Drupal\Core\Config\Entity\ConfigEntityStorage->save(Object) (Line: 339)
Drupal\Core\Entity\EntityBase->save() (Line: 607)
Drupal\Core\Config\Entity\ConfigEntityBase->save() (Line: 392)
Drupal\Core\Config\ConfigInstaller->createConfiguration('', Array) (Line: 99)
Drupal\features\FeaturesConfigInstaller->createConfiguration('', Array) (Line: 152)
Drupal\Core\Config\ConfigInstaller->installDefaultConfig('module', 'ldp_translation') (Line: 327)
Drupal\Core\Extension\ModuleInstaller->install(Array, 1) (Line: 83)
Drupal\Core\ProxyClass\Extension\ModuleInstaller->install(Array) (Line: 175)
Drupal\system\Form\ModulesListConfirmForm->submitForm(Array, Object)
call_user_func_array(Array, Array) (Line: 114)
... snipped

Steps to reproduce

Using a supported version of PHP such as 8.1/8.2/8.3/8.4

Enable some custom or contrib module that has configs to install and the config somehow results in a null uuid. After the module is enabled, the error message will be displayed.

RELATED ISSUES LINKED:

Release notes snippet

Make core more resilient to null uuids when using recent versions of PHP
We have a proven tests only failure.
The solution passes the new test.

Issue fork drupal-3302838

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

ciprian.stavovei created an issue. See original summary.

ciprian.stavovei’s picture

Status: Active » Needs review
StatusFileSize
new660 bytes
fago’s picture

Title: Deprecated function: mb_strtolower(): Passing null to parameter #1 ($string) of type string is deprecated in Drupal\Core\Config\Entity\Query\Condition->compile() » Querying with NULL values results in warning mb_strtolower(): Passing null to parameter is deprecated
Status: Needs review » Needs work

elseif (!is_bool($condition['value'])) {
- $condition['value'] = mb_strtolower($condition['value']);
+ $condition['value'] = mb_strtolower($condition['value'] ?? "");
}

I'm not convinced that we should turn NULL into "" here.

It seems to me the better fix would be to exclude the NULL case from mbstring in the if like

> elseif (!is_bool($condition['value']) && isset($condition['value']))

?

ravi.shankar’s picture

Status: Needs work » Needs review
StatusFileSize
new711 bytes
new790 bytes

Made changes as per comment #3, please review.

ciprian.stavovei’s picture

StatusFileSize
new830 bytes

Added another patch to set the condition value to NULL when no condition is met so that the final result stays the same as before.

fago’s picture

Status: Needs review » Needs work

+ elseif (!is_bool($condition['value']) && isset($condition['value'])) {
$condition['value'] = mb_strtolower($condition['value']);
}
+ else {
+ $condition['value'] = NULL;
+ }

this fails if the value is bool. but when $condition['value'] is already NULL it's not necessary to assign it, so just keeping $condition['value'] and having no else {} part should be fine then?

ciprian.stavovei’s picture

Status: Needs work » Needs review

That's right. It should be disregarded.

fago’s picture

Patch of #7 seems to be wrong if value is FALSE.
Actually, I think patch #4 is correct. if no massaging of the value is necessary, no else {} clause is necessary. Right?

ciprian.stavovei’s picture

Yes, patch #4 is the correct one. In comment #7 I hid patch #5 because it is not correct.

fago’s picture

Status: Needs review » Reviewed & tested by the community

agreed, so #4 is the right fix. I verified it solves the issue as well, so all good then.

catch’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new808 bytes

It looks a little odd to me to check isset() after is_bool(), what about this?

ravi.shankar’s picture

Status: Needs review » Needs work

Setting back to needs work as patch #11 fails.

catch’s picture

Status: Needs work » Needs review
StatusFileSize
new809 bytes

Whoops this time without the syntax error.

ericdsd’s picture

Thanks, #13 fixed the issue on 9.4.5.

heni_deepak’s picture

#13 fixed my issue on 9.5.0-dev

but I have faced issues after adding

TypeError: mb_strtolower(): Argument #1 ($string) must be of type string, array given in mb_strtolower() (line 174 of core/lib/Drupal/Core/Config/Entity/Query/Condition.php).

$block_ids = \Drupal::entityQuery('block')->condition('third_party_settings', Null, '<>')->execute();

jungle’s picture

Status: Needs review » Reviewed & tested by the community

Re #15 try
$block_ids = \Drupal::entityQuery('block')->condition('third_party_settings', 'IS NOT NULL')->execute(); instead?

#13 fixed testPostUpdateTaxonomyIndexFilterMultipleVocabularies() in the patch in comment #212 of issue #2784233: Allow multiple vocabularies in the taxonomy filter

It looks a little odd to me to check isset() after is_bool()

+1

#13 looks good to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

When we had these errors while prepping for PHP 8 we tracked them back to the caller. This error is pointing something else being amiss and not as expected.

jungle’s picture

Status: Needs work » Needs review

>#13 fixed testPostUpdateTaxonomyIndexFilterMultipleVocabularies() in the patch in comment #212 of issue #2784233: Allow multiple vocabularies in the taxonomy filter

FYI, found that it's the view for testing in which the `uuid` is missing, the patch here is no more required.

Judged by the issue summary, the deprecated message was raised while installing a non-core module: `ldp_translation`, per @alexpott's comment, is this a won't fix? Setting back to NR for opinions.

smustgrave’s picture

extexan’s picture

Although the patch in #13 fixed the error for me, while stepping through in debug, I noticed the array_map in line 36 is running against this value:

$condition = {array}
  field = "status"
  value = {array}
    0 => true
  operator = "IN"
  langcode = null

When value is not an array, the elseif at line 38 is checking is_bool(), and skipping the mb_strtolower() if it is. Should it be skipped in line 36 as well?

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Closed (won't fix)
Issue tags: +Needs Review Queue Initiative

Have to be in agreement with @jungle in #19. Seems this patch was just covering a symptom but the cause has been fixed.

If anyone disagrees please reopen with an explanation why.

Thanks!

heddn’s picture

I wonder if closing won't fix is quite what we want to do? Could we complain more loudly or do something to help track down these issues? I regularly see these warnings in test runs and its a bear to figure out where the null is coming from. Being more loud in our logging of the source would be really nice.

joegraduate’s picture

Version: 9.5.x-dev » 10.1.x-dev
Component: install system » configuration entity system
Status: Closed (won't fix) » Needs review
Issue tags: +PHP 8.1
StatusFileSize
new811 bytes

We're seeing these warnings show up in various contexts when using exported configuration entities provided by custom modules in config/install directories that do not have UUIDs. It looks like the Drupal\Core\Config\Entity\ConfigEntityBase::preSave() method uses Drupal\Core\Entity\EntityBase::uuid() when creating query conditions which returns NULL if a UUID doesn't exist.

The attached patch changes those NULL values into empty strings in Drupal\Core\Config\Entity\ConfigEntityBase::preSave() to prevent them from getting passed as query condition values.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update, +Needs tests

The issue summary should be updated with the new proposed solution.

Will also require a test case to show the problem.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

joseph.olstad’s picture

Got this notice/warning in D10 using php 8.1 when switching text format from ckeditor5 to ckeditor4
patch 25 resolves the issue.

lucian.ilea’s picture

Hi!
I confirm that #13 fixed the issue for me on Drupal 9.5.9 with php 8.1.
Thank you!

heddn’s picture

Part of why this is becoming an issue, more and more is because of #3369127: 'filter.format.' . WebformHtmlEditor::DEFAULT_FILTER_FORMAT missing UUID.

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

Ajeet Tiwari’s picture

Status: Needs work » Needs review
StatusFileSize
new711 bytes

kindly review the patch.

smustgrave’s picture

Status: Needs review » Needs work

Still needs tests and issue summary update

suryabhi’s picture

StatusFileSize
new783 bytes

Please review the Patch

suryabhi’s picture

StatusFileSize
new1.42 KB

Added a new patch. Fixing build issue. Please review

suryabhi’s picture

mrinalini9’s picture

Status: Needs work » Needs review
StatusFileSize
new706 bytes

Rerolled patch #36, please review it.

Thanks!

smustgrave’s picture

Status: Needs review » Needs work

Thank you for the interest but please read the tags. Previously tagged for issue summary update and tests.

Also the MR is on the correct branch and should continue there.

joseph.olstad’s picture

"Needs tests"

suryabhi’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work

Still needs a test.

BBaptiste’s picture

Merge request !4263 fixed my issue on Drupal 10.1.2 (PHP 8.1.14 / MySQL 5.7.29)

Thanks.

bjc2265’s picture

I've been unable to reproduce this by enabling modules. Attempted several contrib modules (including ckeditor 4 and 5) in fresh Drupal 10.1.x install.

joseph.olstad’s picture

@bjc2265, are you using PHP 8.0 or PHP 8.1+ ?

This fix is for PHP 8.1+

bjc2265’s picture

Using PHP 8.1.8 and Drupal 10.1.4

Just to confirm: message should appear in GUI after going to Extend tab, selecting a module that changes configuration (such as Configuration Translation or Content Translation) and clicking Install? Because doing that on fresh install I'm not seeing error in logs or as alert.

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

prabuela’s picture

Assigned: Unassigned » prabuela
prabuela’s picture

Assigned: prabuela » Unassigned
eiriksm’s picture

Status: Needs work » Needs review
StatusFileSize
new1.4 KB

I don't know how to do test only patches with gitlab. I also was not able to "claim" push access to the fork

Anyway. Here is a test only patch, please feel free to add to the fork

smustgrave’s picture

Status: Needs review » Needs work

If you click "Get push access" there's an option on the pipeline https://git.drupalcode.org/issue/drupal-3302838/-/pipelines/56031

There you can click "Test-only feature"

Current MR appears to have test failures.

Was previously tagged for issue summary too as some sections appear to be missing.

eiriksm’s picture

I did click the "get push access" and have done so many times before as well. But some hiccup today probably? Tried again now, and now it works :)

Let me try to rebase and get the test only thing in there as well, never tried that before.

Leaving on NW for the issue summary part

smustgrave’s picture

Now will say there's a bug/feature being worked out where if the MR is opened by a core committer, even getting push access you can't run the test-only feature or rerun any tests.

eiriksm’s picture

right. was probably just a hiccup I guess, since both work now.

Link to test-only run: https://git.drupalcode.org/issue/drupal-3302838/-/jobs/799034

smustgrave’s picture

Issue tags: -Needs tests

Removing tests tag

joseph.olstad’s picture

Issue summary: View changes
joseph.olstad’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs issue summary update +PHP 8.2, +PHP 8.3, +PHP 8.4

updated issue summary

joseph.olstad’s picture

Issue summary: View changes
alexpott’s picture

Status: Reviewed & tested by the community » Needs work

As per #18 this is fixing the symptom and not the cause. If a config entity is missing a UUID then a module is doing something wrong. The configuration is not valid.

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

hfernandes’s picture

Status: Needs work » Needs review
Related issues: +#3301613: Only process values in config entity query conditions for values that have values
StatusFileSize
new713 bytes

I am adding another related issue as the solutions are the same.

I'm updating the MR to include the is_string validation since the function mb_strtolower expects a string as parameter.

smustgrave’s picture

Status: Needs review » Needs work

Appears to have test failures.

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

eric_a’s picture

Adding a related contrib issue, from CAPTCHA module.
From #3497314-6: Tests are failing for Drupal 11.1:

This last one is drupal core fault, when saving new config entity on preSave() it tries to load existing entity by uuid in core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php line 308. I didn't find the issue for this on drupal core issues. So now we just pre-fill uuid on new CaptchaPoint creation in captcha_set_form_id_setting()

diff --git a/captcha.inc b/captcha.inc
index 97610420731b23a2d7bf285bff5b0a06a8900715..72bdf9f861c4d847bc689d02ec01399409f057aa 100755
--- a/captcha.inc
+++ b/captcha.inc
@@ -34,6 +34,10 @@ function captcha_set_form_id_setting($form_id, $captcha_type) {
     $captcha_point = new CaptchaPoint([
       'formId' => $form_id,
       'captchaType' => $captcha_type,
+      // @see https://www.drupal.org/project/drupal/issues/3302838
+      // On config pre-save drupal tries to query same uuid, and deprecation
+      // is generated. So we prefill the uuid for now.
+      'uuid' => \Drupal::service('uuid')->generate(),
     ], 'captcha_point');
   }
   $captcha_point->enable();
rajab natshah’s picture

Version: 11.x-dev » main
jlockhart’s picture

StatusFileSize
new6.84 KB

Just adding a new patch from the latest MR.