Problem/Motivation
A fatal PHP 8 TypeError occurs in _wxt_library_check_url() when a site uses Domain-based language negotiation and a user visits an untranslated node.
The error triggered is:
TypeError: mb_strtolower(): Argument #1 ($string) must be of type string, array given in mb_strtolower() (line 151 of modules/contrib/wxt_library/wxt_library.module).Why this happens:
Around line 151 of wxt_library.module, the module attempts to check the path alias:
$path_alias = mb_strtolower(\Drupal::service('path_alias.repository')->lookupBySystemPath($path, 'en') ?? '');The path_alias.repository service is a low-level database query that returns an associative array (id, path, alias, langcode) on a successful match, or NULL on a miss. The code assumes it returns a string and uses the null-coalescing operator ?? '' to prevent errors.
Under Path Prefix language negotiation, Url::fromRoute('<current>')->toString() returns a prefixed path (like /fr/node/123). The repository fails to find a match for this in the database, returns NULL, and the code safely evaluates to an empty string.
However, under Domain language negotiation, Url::fromRoute('<current>')->toString() returns the raw internal path (/node/123). The repository successfully finds the English alias record and returns the row as an array. Because an array is truthy, it bypasses the ?? '' check, gets passed directly into mb_strtolower(), and immediately crashes PHP 8.
Steps to reproduce
- Install WxT and configure Language Negotiation to use Domains (e.g.,
en.example.comandfr.example.com). - Ensure a URL Alias pattern (Pathauto) is configured for a content type (e.g., Basic Page).
- Create a new node in English, ensuring the "Generate automatic URL alias" checkbox is active and an alias is created.
- Do not create a French translation for this node.
- Visit the node on the French domain (the untranslated fallback).
- Observe the WSOD and the resulting TypeError in the logs.
Proposed resolution
Update _wxt_library_check_url() to use the path_alias.manager service instead of the low-level repository. The Alias Manager natively handles language fallbacks and reliably returns a string (the alias, or the original path if no alias exists).
Change:
$string = \Drupal::service('path_alias.repository')->lookupBySystemPath($path, 'en'); $path_alias = mb_strtolower(\Drupal::service('path_alias.repository')->lookupBySystemPath($path, 'en') ?? '');
To:
$string = \Drupal::service('path_alias.manager')->getAliasByPath($path, 'en'); $path_alias = mb_strtolower($string);
Remaining tasks
Create a patch / Merge Request to implement the proposed resolution.
Comments