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.

Fix Munin MySQL Graphs on cPanel

If you have setup munin-node on a cPanel server it’s possible that your MySQL graphs stop updating at sometime, or don’t even generate from the beginning.

To fix, edit the following file:

/etc/munin/plugin-conf.d/cpanel.conf

And make sure that the mysql section contains the following:

[mysql*]
user root
group wheel
env.mysqladmin /usr/bin/mysqladmin
env.mysqlopts --defaults-extra-file=/root/.my.cnf

Setup WordPress CDN with Dediserve

My blog is running on a blazing fast Litespeed-powered server which is located in London, but because most of my visitors are from the US (check out this cool infographic!), I always wanted to setup CDN to speed things up for them too. A CDN can offer tremendous WordPress performance improvements and by utilizing the W3 Total Cache plugin you optimize WordPress from it’s core.
Since there wasn’t any related documentation available, Dediserve was very kind to offer me a free first month on their CDN service to test things out.

What is a CDN

A CDN is a global network of caching servers and smart DNS routing that delivers your content and media to your users from the closest possible location. The result is the fastest possible load times, better Google rankings and less load on your servers!
When US visitors view my blog, images are served from the UK, making it a long way from the visitor to the server. By implementing a CDN, edge servers located all around the world serve those images from the nearest location to the visitor. Dediserve is running on the OnApp CDN engine, and has over 60 locations all around the world at the time of writing.
Continue reading

Centova Cast: Upgrade from Trial to Monthly/Owned License

After trialing Centova Cast v2.2.6 for a few days, I decided to move on and purchase a paid monthly license. Since a new license key needed to be purchased, I started searching about a way to replace my license key on my current installation, but unfortunately I couldn’t find any clear instructions.

By combining information from a few forum posts and knowledge base articles from their website, I finally found a way to do it.

  1. Download their license key update utility
  2. Unzip the contents of the file to the root directory of your Centova Cast web files (eg. /var/www/ or /home/[username]/public_html/)
  3. Launch the script in your broswer: If Centova Cast is installed at http://radio.domain.com then you should launch http://radio.domain.com/licenseupdate.php
  4. Copy the license key of your newly purchased license from your Centova Cast Client Area and click the Update Key button.
  5. SSH to your server and run the command below:
    /home/centovacast/system/runascc/runascc exec ccmanage reissuelicense radio.domain.com

    (replace radio.domain.com with your FQDN you used when purchasing your license)

You should receive output similar to the following:

INF License reissuance forced; renewing license information (this may take a few moments) ...
OK Key updated; new renewal date: 2012-03-07 10:13:39

Your license key is now updated and you’re ready to roll. Happy streaming!

Fix Unknown table engine ‘INNODB’ error on Munin

In newer MySQL versions, if you have InnoDB disabled, Munin will fail to run giving you the following error:

root@myserver [~]# munin-run mysql_connections
DBD::mysql::st execute failed: Unknown table engine 'INNODB' at /etc/munin/plugins/mysql_connections line 958.

This is caused because the error message is changing between versions and the mysql_ plugin for munin hasn’t been updated in order to recognize it.
The fix is pretty simple, just open /usr/share/munin/plugins/mysql_ with vim on line 958 (hint: vim +958 filename) and replace as bellow.

Original code

    if ($@) {
 	        if ($@ =~ /Cannot call SHOW INNODB STATUS because skip-innodb is defined/) {
 	            $data->{_innodb_disabled} = 1;
 	            return;
 	        }
 	        die $@;

Fixed code

    if ($@) {
 	        if ($@ =~ /Unknown table engine 'INNODB'|Unknown storage engine 'innodb'|Cannot call SHOW INNODB STATUS because skip-innodb is defined/i) {
 	            $data->{_innodb_disabled} = 1;
 	            return;
 	        }
 	        die $@;

Save the file and you’re good to go 🙂

Monitoring bind/named with Munin on cPanel DNS Only

Last night I attempted to get named monitoring working with Munin on my two cPanel DNS Only boxes. Named is actually the most important service to monitor on a DNS Only box so in my opinion it should be enabled by default when you install Munin via WHM.
The whole process was actually really straightforward and the only thing I had to do was to apply a set of Debian instructions I found here, on CentOS. Here’s how you can install Munin and setup named monitoring Continue reading

iOS 5.0.1 beta fixes battery issue

[blackbirdpie url=”https://twitter.com/#!/iMZDL/status/132175470253973504″]

In a previous post I mentioned that after installing the GM (i.e. final) version of iOS 5, I’ve seen my battery life percentage drop below 20% in a matter of a few hours. Now after upgrading to beta 1 on Thursday and beta 2 yesterday, and I can confirm that the battery issue is now fixed 🙂
My iPhone 4 now easily goes over 24+ hours after a full charge with everything enabled! (3G, WiFi, Location services etc.)

How To: Restore Default Settings on Safari (Mac OS X Lion)

I just installed the Mac OS X Lion 10.7.2 GM update and noticed that Safari was behaving a bit weird after the update so I thought I reset it’s settings to default.

Here’s how it’s done:

1. Open Safari and click on Safari in the upper left hand corner.
2. Click Reset Safari.

3. Restart Safari. This will resolve most problems. If this does not solve the problem, proceed on to Step 4.
Continue reading