InvalidArgumentException: The user-entered string must begin with a '/', '?', or '#'.

Created on 15 May 2025, 3 days ago

Problem/Motivation

When working with Drupal 10.4, I noticed the following error:

InvalidArgumentException: The user-entered string 'https://test.ddev.site/en/admin/content' must begin with a '/', '?', or '#'. in Drupal\Core\Url::fromUserInput() (line 216 of core/lib/Drupal/Core/Url.php).
Drupal\type_tray\Controller\TypeTrayController->addPage(Object) (Line: 23)
Drupal\gin_type_tray\Controller\GinTypeTrayController->addPage(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 638)

Steps to reproduce

Spool up a site in DDEV using Drupal's WxT Profile, once its running, visit the Add Content and try to add a Basic Page.

Proposed resolution

Looking at the offending code I found this:

          // @codingStandardsIgnoreLine
          $all_nodes_label = $this->t($settings['existing_nodes_link_text']);

          // Remove scripts/style from the label.
          $all_nodes_label = Xss::filterAdmin($all_nodes_label);

          $admin_content_url = Url::fromRoute('system.admin_content')->toString();
          $all_nodes_url = Url::fromUserInput($admin_content_url, ['query' => ['type' => $type->id()]]);
          $build['#items'][$category][$type->id()]['#nodes_by_type_link'] = Link::fromTextAndUrl($all_nodes_label, $all_nodes_url);

There are a few things I believe to be causing the problem here:

  1. The Class Url and its method fromUserInput is expecting a path and not a fully qualified domain name. Hence the error.
  2. The $all_nodes_label can have HTML in it which leads to html converted characters.

I propose the following patch to resolve some of these issues and better contextualize the mechanism:

          $admin_content_url = Url::fromRoute('system.admin_content', ['type' => $type->id()]);
          $build['#items'][$category][$type->id()]['#nodes_by_type_link'] = [
            '#type' => 'link',
            '#title' => [
              '#markup' => $all_nodes_label,
            ],
            '#url' => $admin_content_url,
            '#options' => ['html' => TRUE],
          ];

Here we pass the type for the admin_content_url straight into the fromRoute method, alleviating the need to use a second method and we build the item as a link markup passing the option "html" as true. This allows the link to render the HTML in the label and improving the extensibility of the code.

🐛 Bug report
Status

Active

Version

1.3

Component

Code

Created by

🇨🇦Canada wilco

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

Comments & Activities

Production build 0.71.5 2024