Problem/Motivation

The search indexing process in Drupal fails to correctly handle HTML tags that contain whitespace characters (tabs, newlines) between the tag name and attributes. When node content contains such HTML tags (e.g., <a\n href="..."> or <a\t href="...">), the following issues occur:

1. PHP Warning: "Undefined array key" errors when the tag name with trailing whitespace is used as an array key
2. Incorrect search ranking: Tags are not properly recognized, resulting in improper scoring of search results

The root cause is that the code uses explode(' ', $value, 2) which only splits on space characters, not on other whitespace characters like tabs or newlines that are valid in HTML.

Error Example

Warning: Undefined array key "a
"
Drupal\search\SearchIndex->index()() (Line: 112)

Impact

This affects any content with multi-line HTML tags, which can occur when:

  • Using custom text formats without CKEditor or other WYSIWYG editors
  • Content is imported from external sources (RSS feeds, migrations, API integrations)
  • Nodes are created programmatically via custom modules or APIs
  • Database imports or bulk content updates

Note: Standard text formats (Full HTML, Basic HTML) typically use CKEditor, which automatically normalizes HTML. However, custom text formats without WYSIWYG editors allow users to enter multi-line HTML directly.

Steps to reproduce

Method 1: Using UI with custom text format (newline case)

  1. Create a custom text format without any filters:
    • Go to /admin/config/content/formats/add
    • Create a format without enabling any text editor
  2. Create a node using this text format and enter HTML with newlines in the textarea:
    <a
      href="https://example.com/"
    >
      Drupal Rocks
    </a>
    
  3. Save the node
  4. Run search indexing: drush cron
  5. Check the search index score in the database:
    SELECT word, score FROM search_index WHERE word = 'rocks';
    

    Expected score for <a> tag content: 11

    Actual score with bug: 1 (incorrect - treated as plain text)

Method 1b: Using UI with custom text format (tab case)

Follow the same steps as Method 1, but enter HTML with a tab character between the tag name and attribute (represented as \t below):

<a\thref="https://example.com/">Drupal Rocks</a>

Method 2: Programmatic reproduction

use Drupal\node\Entity\Node;

$node = Node::create([
  'type' => 'page',
  'title' => 'Test multiline tags',
  'body' => [
    'value' => '<a
      href="https://example.com/"
    >
      Drupal Rocks
    </a>',
    'format' => 'plain_text',
  ],
]);
$node->save();

Proposed resolution

Modify SearchIndex::index() to use preg_split() instead of explode() to properly handle all whitespace characters (space, tab, newline, etc.) between tag names and attributes.

Change in core/modules/search/src/SearchIndex.php:86:

// Before:
[$tagname] = explode(' ', $value, 2);

// After:
[$tagname] = preg_split('/\s+/', $value, 2);

This ensures that:

  • Tag names are properly extracted regardless of whitespace type (space, tab, newline)
  • Array key lookups succeed without warnings
  • Search ranking scores are correctly applied according to HTML tag weights

Remaining tasks

Discuss how to handle existing search indexes created before this fix (reindex required vs. gradual update).

User interface changes

None. This is an internal bug fix with no UI changes.

Introduced terminology

None.

API changes

None. This is an internal implementation fix with no API changes.

Data model changes

None.

Release notes snippet

Fixed a bug in the search indexing process where HTML tags with whitespace characters (newlines, tabs) between tag names and attributes would cause PHP warnings and incorrect search ranking scores.

Issue fork drupal-3564713

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

u7aro created an issue. See original summary.

u7aro changed the visibility of the branch 11.x to hidden.

u7aro’s picture

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

u7aro changed the visibility of the branch 11.x to active.

u7aro changed the visibility of the branch 3564713-search-module-fails to hidden.

u7aro changed the visibility of the branch 11.x to hidden.

u7aro’s picture

Issue summary: View changes
u7aro’s picture

Status: Active » Needs review

I’ve created a merge request.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

Left a comment on the MR around the test.

u7aro’s picture

Status: Needs work » Needs review

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Believe feedback for this one has been addressed. https://git.drupalcode.org/issue/drupal-3564713/-/jobs/8410601 shows the test coverage too.

  • godotislate committed 7bef38be on main
    fix: #3564713 Search module fails to handle HTML tags with whitespace...

  • godotislate committed ffa40d45 on 11.x
    fix: #3564713 Search module fails to handle HTML tags with whitespace...

  • godotislate committed ed5ff2b3 on 11.3.x
    fix: #3564713 Search module fails to handle HTML tags with whitespace...

godotislate’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed to main, 11.x, 11.3.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

godotislate’s picture

Version: main » 11.3.x-dev

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.