TypeError: strlen(): Argument #1 ($string) must be of type string, array given

Created on 4 April 2025, about 1 month ago

I am seeing an error with big pipe, call stack below.

Error shows Drupal core 10.4.5 and 10.4.6. PHP 8.2. both on Linux (Ubuntu) and Windows systems.
Error appears after an upgrade from a much older 10.1.3 version to 10.4.5. Also, a PHP upgrade from 8.1 to 8.2.
(On Drupal 10.1.3 and PHP 8.1 there were no errors and it worked fine).

Symptoms: A minimal custom block that is normally shown in the sidebar is no longer shown. At that time, consistently, the error below appears in the log.

I checked the code, the block shows a minimal form that builds four links and one submit button. I don't see anything special in it. The block is NOT cached with getCacheMaxAge() { return 0; }
Strangely, the block appeared fine during upgrade testing with existing content. Once we put it on live and generated new content/pages that show the block, everything broke and it disappeared everywhere, even on the older content pages.

Workaround: Turn off "Big Pipe" module and everything works fine again. So while the error appears in Unicode.php, I believe it is some sort of argument that would be passed down from Big Pipe.

I am not sure how you could reproduce it, but maybe the short stacktrace below gives a hint where a wrong argument may be passed.

Here is the stack trace:

TypeError: strlen(): Argument #1 ($string) must be of type string, array given in strlen() (line 395 of C:\...\\core\lib\Drupal\Component\Utility\Unicode.php)

#0 C:\...\core\lib\Drupal\Component\Utility\Unicode.php(395): strlen(Array)
#1 C:\...\core\lib\Drupal\Component\Utility\Xss.php(65): Drupal\Component\Utility\Unicode::validateUtf8(Array)
#2 C:\...\core\lib\Drupal\Component\Utility\Xss.php(123): Drupal\Component\Utility\Xss::filter(Array, Array)
#3 C:\...\core\lib\Drupal\Core\Ajax\MessageCommand.php(127): Drupal\Component\Utility\Xss::filterAdmin(Array)
#4 C:\...\core\lib\Drupal\Core\Ajax\AjaxResponse.php(43): Drupal\Core\Ajax\MessageCommand->render()
#5 C:\...\core\modules\big_pipe\src\Render\BigPipe.php(567): Drupal\Core\Ajax\AjaxResponse->addCommand(Object(Drupal\Core\Ajax\MessageCommand))
#6 C:\...\core\modules\big_pipe\src\Render\BigPipe.php(283): Drupal\big_pipe\Render\BigPipe->sendPlaceholders(Array, Array, Object(Drupal\Core\Asset\AttachedAssets))
#7 C:\...\core\modules\big_pipe\src\Render\BigPipeResponse.php(113): Drupal\big_pipe\Render\BigPipe->sendContent(Object(Drupal\big_pipe\Render\BigPipeResponse))
#8 C:\...\vendor\symfony\http-foundation\Response.php(423): Drupal\big_pipe\Render\BigPipeResponse->sendContent()
#9 C:\...\index.php(20): Symfony\Component\HttpFoundation\Response->send()
#10 {main}

🐛 Bug report
Status

Active

Version

10.4

Component

big_pipe.module

Created by

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

Comments & Activities

  • Issue created by @hoporr
  • What is in the array passed to strlen in Unicode.php on line 395?

  • 🇺🇸United States mdziedzic

    I'm not the original poster, but we also have this issue and I was able to track down the cause. Short story is that Drupal Messenger objects can accept either a string OR markup array. And when the message rendering is called, it does not verify the type before passing it to Xss::filterAdmin and then to Unicode::validateUtf8 which both only accept strings.

    So, for example, when calling

    \Drupal::messenger()->addWarning(['#markup' => '<p class="usa-alert__text">This is my markup/p>']);

    You get:
    ....
    MessageCommand->render line 127 calls : Xss::filterAdmin($this->message),
    Xss::filterAdmin(Array)
    -- and later --
    Unicode:: validateUtf8(Array) which fails on line 399:

        if (strlen($text) == 0) {
          return TRUE;
        }

    From a security standpoint, I'm not sure what the appropriate fix is to continue diligence against XSS when its a markup object being passed.

  • 🇧🇪Belgium økse

    økse made their first commit to this issue’s fork.

  • 🇧🇪Belgium økse

    Since the error clearly indicates that the first argument ($message) must be of the type string, I did add a patch to flatten arrays to a string. Also, anything else will be safely casted to a string.

Production build 0.71.5 2024