Monthly Archives: August 2026

Debugging a WP Toolkit scan failure: “Invalid field: auto_update”

While importing an existing WordPress installation into WP Toolkit on one of our cPanel servers, the scan failed with an error that, at first glance, made no sense:

Failed to register instance at '/home/example/public_html':
Failed to reset cache for the instance #51: Error: Invalid field: auto_update.

[error]FailedToExecuteWpCliCommand: exit status 1[/error]

The site was running WordPress 6.9.5. The server had WP-CLI 2.12.0. Both are far newer than anything that could plausibly not know about the auto_update field, which has existed since WordPress 5.5 and WP-CLI 2.5 — that’s 2020. And yet, here we were.

This post walks through the investigation, because the root cause turned out to be something that can silently affect any cPanel account, and the symptom points everywhere except the actual problem.

What the error means

During a scan, WP Toolkit runs WP-CLI commands like this against each installation it discovers:

wp plugin list --fields=name,status,update,auto_update

If WP-CLI can’t produce one of the requested columns, it errors out with Invalid field, and WP Toolkit fails to register the instance. So the question was simple: why would a current WP-CLI, against a current WordPress, refuse to produce a column it has supported for six years?

Ruling out the obvious suspects

Old WordPress core? No — wp core version reported 6.9.5.

A plugin disabling auto-updates? WP-CLI only exposes the auto_update column when the auto-update system is actually enabled for that site, so a plugin hooking automatic_updater_disabled could in theory cause this. But the error survived --skip-plugins --skip-themes, which rules out plugin and theme code entirely.

Constants or drop-ins? A quick wp eval-file diagnostic asking WordPress directly settled it:

array (
  'auto_update_enabled_plugin' => true,
  'updater_is_disabled'        => false,
  'file_mod_allowed'           => true,
  'DISALLOW_FILE_MODS'         => 'undefined',
  'AUTOMATIC_UPDATER_DISABLED' => 'undefined',
  'filter_auto_updater'        => false,
  'filter_file_mod'            => false,
)

Every gate was open. WordPress itself was perfectly happy to auto-update. The environment wasn’t the problem.

(Small CageFS aside: the diagnostic script had to live inside the user’s home directory. /tmp as root and /tmp inside the user’s cage are different filesystems, so a script dropped into /tmp as root simply doesn’t exist from the user’s point of view.)

The tell

If WordPress wasn’t hiding the field, then the command code itself had to be old — regardless of what the version string claimed. And there’s a quick way to check what the running command actually supports:

# wp help plugin list | grep auto_update
(no output)

The plugin list command in use didn’t document auto_update at all. The framework said 2.12.0, but the command behaved like something from 2020.

Root cause: a forgotten wp package install

WP-CLI supports user-installed packages under ~/.wp-cli/packages/. On this account, someone had at some point installed two of them:

# wp package list
+------------------------+----------+
| name                   | version  |
+------------------------+----------+
| wp-cli/doctor-command  | dev-main |
| wp-cli/profile-command | dev-main |
+------------------------+----------+

Harmless-looking. But packages are installed via Composer with their own dependency tree, and a look inside the vendor directory told the real story:

# ls ~/.wp-cli/packages/vendor/wp-cli/
checksum-command  core-command  cron-command  doctor-command
entity-command  extension-command  language-command  profile-command

Those old package installs had pulled in half of WP-CLI’s command suite as dependencies — including extension-command, which is what actually provides wp plugin list and wp theme list. And here’s the critical detail: anything in the packages vendor directory overrides the commands bundled in the phar.

So every wp invocation on this account — including the ones WP Toolkit’s scanner runs as the user — was loading a 2020-era plugin list implementation that predates the auto_update field. The phar itself was current; it just never got a say.

The fix

wp package uninstall seemed like the clean way out, but it failed (Composer return code 2 — it wants to reach Packagist to regenerate the autoloader, which doesn’t work from inside the cage). No matter — the packages directory is entirely disposable. It contains only optional packages and their autoloader, nothing about the sites themselves:

mv ~/.wp-cli/packages ~/.wp-cli/packages.bak

Immediately afterwards:

# wp plugin list --fields=name,status,update,auto_update
+---------------------+--------+-----------+-------------+
| name                | status | update    | auto_update |
+---------------------+--------+-----------+-------------+
| woocommerce         | active | none      | off         |
| elementor           | active | available | off         |
| ...                 |        |           |             |

A rescan in WP Toolkit registered the site cleanly.

One more footnote: the failed scans had referenced instance IDs that didn’t exist in wp-toolkit --list. That’s expected — WP Toolkit creates the instance record at the start of registration and rolls it back on failure, so failed attempts simply burn auto-increment IDs. Nothing to clean up.

Takeaways

  1. wp cli version doesn’t tell you what code your commands run. The framework version and the command implementations can diverge if packages are installed. wp help <command> shows what the running implementation actually supports.
  2. wp package install has a long tail. A package installed once for a debugging session years ago can silently pin core commands to ancient versions via its Composer dependencies — and keep them pinned through every WP-CLI upgrade since.
  3. When a tool errors on a field the whole stack should support, suspect the dispatch path, not the stack. WordPress was fine, WP-CLI was fine, WP Toolkit was fine. The problem was which code got loaded.
  4. If you manage cPanel servers: it’s worth a periodic sweep for ~/.wp-cli/packages/ directories across accounts. Any account that has one is a candidate for this exact failure mode.