Troubleshooting

Find the symptom, read the cause, apply the fix. Errors from the plugin always carry a code such as wpcb_unauthorized; search this page for it, or press / and type it.

On this page

Three checks that solve most problems

  1. Is the plugin answering? Open https://your-site.example/wp-json/wpcb/v1/health in a browser. You should see "status":"ok" and the plugin version. A 404 means the plugin is not active, or the REST API is blocked by a security plugin or the server.
  2. Is the token alive? In Xaflo → Tokens, check that it is not expired or revoked. If in doubt, create a new one.
  3. Did the client restart? AI clients start MCP servers when they launch. After any change to the configuration, quit the client completely and open it again. In Claude Code, /mcp shows each server and whether it connected.

After updating to 1.7.0

Plugin 1.7.0 changed several rules on purpose. If something stopped working right after the update, it is probably one of these. The full list of steps is in Upgrading to 1.7.0.

Every token answers 401

Expected after Rotate secret: rotating invalidates every token. Create new tokens in Xaflo → Tokens and replace them in each client. Until you rotate, old tokens keep working, but rotating is required.

403 xaflo_fs_outside_uploads

site:write now changes files only inside wp-content/uploads, and only documents, images, audio, video and archives. To change theme or plugin files, or anything else outside uploads, the token needs fs:admin as well, and an administrator account. Protected files such as wp-config.php and .env never change.

/db/query answers 409, or refuses a query that used to work

  • Writes need the users, usermeta, options and token tables to use InnoDB.
  • The whole route is refused when MySQL runs with NO_BACKSLASH_ESCAPES or ANSI_QUOTES, with a big5, cp932, gbk, gb18030 or sjis connection, or when those settings cannot be read. Ask your host about the SQL mode.
  • With params, only bare %s, %d and %f are accepted; codes such as unsupported_placeholder mean a % must go in as a value.
  • The route needs an administrator account, and password hashes come back as [redacted: password hash].

The IP allow-list is not enforced

A list saved under 1.6.0 is enforced only after you save it again from Xaflo → Settings. The page shows whether it is enforced, saved but not enforced, or off.

A token made by an Editor or Author is refused

Every token route now checks a WordPress capability. Content keeps working, but database, file, backup, maintenance and similar routes need a token created by an administrator.

“Open wp-admin” does not sign me in

Quick login needs plugin 1.7.0, a token with admin:login created by an administrator, and HTTPS (426 otherwise). It is refused while a known two-factor sign-in plugin is active (409 wpcb_login_link_2fa), and when your address is outside the IP allow-list. Each link works once, for 60 seconds.

Deploy or zip install is refused

wpcb_hash_mismatch: the zip changed on the way. wpcb_too_large: over 20 MB or the server’s upload limit. wpcb_invalid_package: not exactly one plugin folder with a Plugin Name: header. Replacing a plugin that is already installed asks for confirmation first.

Errors from the API

401 wpcb_unauthorized

The request had no valid token: it is missing, mistyped, expired, revoked, or was issued by another site.

  • Copy the token again; it is shown only once, so if it is lost, create a new one.
  • Some hosts strip the Authorization header before PHP sees it. The plugin also accepts the token in X-WPCB-Authorization and reads the server variables Apache uses for a forwarded header. On Apache you can pass the header through with this line in .htaccess:
.htaccess
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

“Issuer mismatch”

The token was created on a different site address: www versus no www, a staging copy, or a site that moved domain. Tokens are only valid for the address that issued them. Create a new token on the site as it is now.

403 wpcb_forbidden

The token is valid but not allowed to do this. Either it lacks the scope, or the WordPress user who created it lacks the capability (an Editor cannot install plugins, whatever the token says). Add the scope in a new token, or create the token as an administrator. Admin-only routes, such as the audit log, answer “Admin only.”

426 wpcb_upgrade_required

The request came over plain HTTP. The plugin only accepts HTTPS, except on local development hosts (localhost, 127.0.0.1, *.localhost, *.test, *.local). Use the https:// address of your site in the configuration, and make sure the site itself is served over HTTPS.

428 wpcb_confirmation_required

Not an error: the operation is destructive and needs a second, explicit step. The response carries a confirmation_token and a summary of what will happen. Your assistant shows you the summary and repeats the call with the token. How confirmation works.

wpcb_confirmation_invalid means the confirmation token expired (after 5 minutes), was already used, or belongs to a different operation. Start the operation again.

429 wpcb_rate_limited

The token made too many requests in a minute: 60 by default, fewer for sensitive scopes. Wait for the number of seconds in the Retry-After header and continue. If a long job keeps hitting the limit, ask the assistant to work in smaller batches, or raise the limit in the plugin settings. Limits per scope.

Setup problems

“A signing secret must be added to wp-config.php before API tokens can be issued.”

No token can be created until WPCB_JWT_SECRET exists. Go to Xaflo → Settings and install the secret, or add the suggested line to wp-config.php yourself. Step by step.

The tools don’t show up in Claude or ChatGPT

  • Quit and reopen the client; reloading a window is not enough.
  • Xaflo Desktop 2.0.1 and later carry the MCP server and repair broken entries at start: update it, then use Set up Claude and ChatGPT on the site again. Without Desktop, check that the server is installed: npm ls -g claude-wp-mcp should list it.
  • Check the configuration for typos in --site and --token, and that the JSON is valid.
  • Without Xaflo Desktop, the MCP server needs Node.js 18 or later: node --version.

The Audit Log page says “Request failed”, or Maintenance says “Missing authorization header”

Fixed in plugin 1.5.1: those admin pages now accept your logged-in session. Update the plugin from Plugins; the current version is 1.7.0.

WordPress doesn’t offer the new version

WordPress checks for plugin updates on its own schedule. Use the Check for updates link on the plugin’s row in Plugins, or install the zip from the Download page over the old one.

Content problems

I asked to publish and it was saved as a draft

The token has content:write but not content:publish. Creating or updating with status “publish” then saves a draft, by design. Add content:publish to the token, or publish from WordPress.

Scripts, styles or attributes disappeared from my page

WordPress filtered the markup because the user behind the token cannot post unfiltered HTML. The write response says so with content_filtered: true. Tokens created by an administrator (who has unfiltered_html) save markup as sent. To stop WordPress from adding paragraphs around a layout, send content_format: "html", which wraps it in a Custom HTML block.

Multilingual tools find no languages

The multilingual tools work through WPML today. On a site without it, wp_multilingual_detect reports the adapter null and the other multilingual tools have nothing to work on. The health endpoint shows the same in its multilingual field.

Analytics tools return nothing

The analytics tools read from an analytics plugin already on the site. Ask the assistant to run wp_analytics_detect first: it tells you which source, if any, it found.

Advanced tools

wp_cli_exec says WP-CLI is disabled

It is off on every site until the site owner turns it on (option wpcb_cli_enabled) and WP-CLI is installed on the server. Even then it runs only an allow-list of commands, such as cache flush, transient delete --all, option get or core version. Since 1.7.0 the command must match an entry exactly, with values in args and only the flags allowed for that command. It needs the cli:exec scope and an administrator token.

A SQL query is rejected

The SQL guard allows one statement at a time, only on tables with your site’s prefix, and only SELECT unless the call asks for write mode with db:write, which then asks for confirmation. Schema changes (DROP, ALTER, CREATE…), file access, timing functions, other databases, WITH and executable comments are always refused, each with its own code. A SELECT without LIMIT returns at most 1000 rows. See also /db/query answers 409.

Still stuck?

Look in Xaflo → Audit Log: every call is there with its result and error message. Then contact us with the error code, the plugin version from /health, and what you asked the assistant to do.