Skip to content

wp search-replace silently writes malformed URLs causing fatal error on next page load #231

@wojsmol

Description

@wojsmol

Bug Report


Describe the current, buggy behavior

When running wp search-replace during a site migration, WP-CLI accepts any replacement string without validating it. If the user makes a typo in the new URL — for example http;//localhost instead of http://localhost (; instead of :, a common keyboard mistake when typing without Shift) — the invalid value is written silently to all tables, including siteurl and home in wp_options.

WP-CLI reports success (X replacements made), giving no indication that anything is wrong. On the next page load, WordPress throws a fatal error:

Fatal error: Uncaught ValueError: setcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014"
in /public_html/wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/src/cookie.php on line 88

The error originates in cookie-handling code (WordPress core or plugins such as Polylang, WooCommerce, etc.) and gives no hint that the root cause is a typo in the wp search-replace replacement string.

The user sees WordPress's built-in fatal error screen ("There has been a critical error on this website"), which confirms something is broken but still gives no indication that the root cause is a malformed URL written by wp search-replace. The actual ValueError and its cause remain hidden without WP_DEBUG enabled or access to the server error log.


Describe how other contributors can replicate this bug

  1. Set up a WordPress installation with a working siteurl and home, e.g. https://production.example.com
  2. Run a migration search-replace with a typo in the replacement URL:
wp search-replace 'https://production.example.com' 'http;//localhost' --all-tables
  1. Visit any page of the site

WP-CLI will report success. The site will throw a fatal ValueError in setcookie() on the next page load. The error message references cookie path handling and gives no indication that the replacement URL is malformed.


Describe what you would expect as the correct outcome

WP-CLI should detect that the replacement string contains characters that are illegal in cookie paths (;, ,, space, tab, etc.) when replacing known URL fields (siteurl, home), and either:

  • Abort with a clear error: "The replacement string does not appear to be a valid URL. Aborting."
  • Or at minimum, print a warning before proceeding: "Warning: replacement string contains characters that may cause issues in cookie paths."

At the very least, the replacement string should be validated as a well-formed URL when it will affect siteurl or home.


Let us know what environment you are running this on

(Paste the output of "wp cli info" into this box)

Confirmed to affect:

  • PHP 8.0+ (where setcookie() throws a fatal ValueError instead of silently ignoring illegal characters as PHP 7.x did)
  • Any WordPress version that derives COOKIEPATH / SITECOOKIEPATH from siteurl / home

Provide a possible solution

In the search-replace command, validate the replacement string as a URL if it resembles one (starts with http:// or https://). Specifically:

  • Check for characters forbidden in cookie paths: ;, ,, space, \t, \r, \n
  • If found, abort or warn before writing to the database

Alternatively, an interactive prompt such as "Replacement string looks unusual, continue? [y/N]" could help catch such typos before any data is written.


Provide additional context

This issue became significantly more impactful with PHP 8.0, which changed setcookie() behavior from silently ignoring invalid path characters to throwing a fatal ValueError. Sites that had malformed URLs in their database for years without issues will now crash immediately after migrating to PHP 8+.

The wp search-replace command is the standard recommended tool for WordPress migrations, making it the most common entry point for this class of error. The combination of factors below makes it difficult to diagnose without prior knowledge, particularly on shared hosting:

  • wp search-replace reports success with no warnings
  • The site shows WordPress's generic critical error screen with no details about the cause
  • The server error log — if accessible at all — points to cookie-handling code, not to the malformed URL
  • The connection between a typo in the migration command and a fatal error in cookie handling is non-obvious

OS: Linux 4.18.0-553.111.1.lve.el8.x86_64 #1 SMP Fri Mar 13 13:42:17 UTC 2026 x86_64
Shell: /bin/bash
PHP binary: /opt/alt/php83/usr/bin/php
PHP version: 8.3.30
php.ini used: /opt/alt/php83/etc/php.ini
MySQL binary: /usr/bin/mariadb
MySQL version: mariadb from 11.4.10-MariaDB, client 15.2 for Linux (x86_64) using EditLine wrapper
SQL modes:
WP-CLI root dir: phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir: phar://wp-cli.phar/vendor
WP_CLI phar path: phar:///home/yser/bin/wp-cli.phar
WP-CLI packages dir: /home/user/.wp-cli/packages/
WP-CLI cache dir: /home/user/.wp-cli/cache
WP-CLI global config:
WP-CLI project config:
WP-CLI version: 2.12.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions