Undo Token Errors
You called royal_mcp_undo_last_operation with the token from a prior write, but it returned an error instead of reversing the operation. This doc lists every error code the undo tool returns, why it fires, and how to fix it. The error code is always in the response's content[0].text field prefixed by the code name (e.g. token_expired: Undo token has expired.).
- Every destructive Pro tool returns an
undoobject in its response envelope:{token, expires_at, ttl_hours}. - Default TTL is 72 hours. Some tool families override to longer (SEO / Widget / Redirection bulk writers use 168h, i.e. 7 days).
- Tokens are one-shot — consumed on the first successful undo. Subsequent calls with the same token fail.
- Cap check requires you to be the original actor who ran the tool, OR to hold
royal_mcp_pro_undo_any, OR to havemanage_options, OR to be a super-admin (multisite). - Read-only tools (like
wp_audit_seo_bulk) return a no-op undo token for API consistency — redeeming it is a no-op success, not an error.
The 6 error codes
token_not_found
The token you passed doesn't exist in the undo store. Either you never had one to begin with (empty undo_token arg), the string is wrong (typo, truncated, extra whitespace), or the row was already purged by the database's retention job.
Fix
- Empty arg: Undo tool requires the
undo_tokenargument. If you calledroyal_mcp_undo_last_operationwith no arg, or your MCP client dropped the field silently, that fires this error. - Wrong token: The correct token is the 64-character hex string in the
undo.tokenfield of the tool response you're trying to reverse. Not theaudit_id, not the tool name, notexpires_at. - Purged row: A daily sweep deletes undo rows that are either consumed OR expired more than 30 days ago (filter:
royal_mcp_pro_undo_retention_days, default 30). Tokens from writes more than ~a month past their TTL are genuinely gone from the store — consider a SiteVault restore instead. If the write is recent but the token itself is truly past-TTL and still in the store, you'll seetoken_expiredinstead.
token_consumed
The token was valid, but somebody (possibly you, in a prior session) already used it. Undo tokens are one-shot; once redeemed, they can't be redeemed again.
Fix
Check the site's Audit Log — a successful undo of this token would have written a row indicating the operation was undone. If you're trying to reverse an operation that was already reversed, the state is what you wanted; no further action needed.
If the audit log doesn't show an undo but the token is marked consumed, that's unusual. Include the audit_id from the token error's structured content in a support email so we can trace what happened.
token_expired
The token is real and was never consumed, but the current time is past its expires_at. Undo runway is 72h by default (168h for SEO / Widget / Redirection bulk).
Fix
Undo is no longer possible via the token path. For most Pro tools, you have three recovery options:
- SiteVault restore if you took a backup before the operation. Match on the timestamp shown in the original write's audit-log row.
- Manual reverse using the Pro tool's inverse operation (e.g.
wp_bulk_update_productscan reverse a prior price update by writing the old prices back). - WordPress revision restore for post-content writes — every Pro tool that modifies post_content also writes a revision, viewable in wp-admin under Revisions on the affected post.
The 72h/168h TTL is a hard limit designed to keep the undo store from growing unbounded — not configurable per-request.
undo_handler_missing
The token is valid and unconsumed, but no undo handler is registered for the tool that created it. This should never happen in a normal Royal MCP Pro install — every destructive Pro tool registers its own undo handler at plugin bootstrap.
Fix
- Confirm Royal MCP Pro is active — if the plugin was deactivated after the tool ran but before you tried to undo, the handler isn't loaded and this error fires. Re-activate the plugin, then retry.
- Confirm you're on the same major version — if you upgraded / downgraded Royal MCP Pro between the write and the undo attempt and the tool's handler moved / renamed across versions, the old token's
tool_namemay not match any current handler. Rare, but happens on rapid upgrade cycles. Contact support with thetool_namefrom the error response.
undo_handler_failed
The handler was invoked but threw an exception while trying to reverse the operation. Common cause: the data state changed since the original write (rows deleted by another process, referenced posts trashed, database schema altered) so the reverse can't safely apply.
Fix
The exception's message is included in the error response's content[0].text. Read that first — it often names the specific row / post that couldn't be restored.
Once the handler starts and fails partway through, the operation is in a half-restored state. Do NOT re-run undo with the same token — it was consumed on the first (failed) attempt, so you'd get token_consumed now anyway. Instead:
- Read the exception message to identify what specifically failed
- Fix the state issue if possible (restore the deleted parent post, roll back the schema change)
- Manually reverse the remaining rows using the Pro tool's inverse operation
insufficient_caps
You're logged in as a user who doesn't have the capability to undo this operation. The undo tool enforces one of: original actor, royal_mcp_pro_undo_any capability, manage_options capability, or super-admin (on multisite).
Fix
The error response includes the original_actor_id field in its structured content. Options:
- Log in as the original actor and retry (usually the AI-flow user whose credentials the MCP call ran under)
- Grant the current user
manage_optionsif they're an admin who should be able to undo any operation. Most WordPress admin accounts already have this. - Grant the
royal_mcp_pro_undo_anycapability to a specific role that isn't an admin but should be able to undo (e.g. a shop-manager-plus role). Use a capabilities plugin (Members, User Role Editor) to add the cap to that role.
The cap check is deliberately strict for operations that could touch sensitive data — letting anyone with an MCP session undo any other user's writes would be a real security issue.
Race conditions
Two concurrent undo attempts against the same token: the first wins, the second gets whatever state the row landed in (token_consumed most commonly, sometimes token_expired if the TTL crossed during the race window). The error message will say "Undo token state changed mid-request" when the race is detected explicitly.
You don't have to do anything about race errors — they're just informing you that the operation was already handled by another process. Check the audit log to confirm the outcome.
Where to find a token after the fact
If you didn't save the token from the original tool response and need to try again later:
- Open the Royal MCP Pro Audit Log page in wp-admin
- Find the row for the operation you want to reverse
- Click View Details to expand it — the
undo_tokenis stored on the row (as long as the token hasn't been purged) - Copy the token, then paste into an MCP call:
Call royal_mcp_undo_last_operation with undo_token="{paste}"
Note that the audit-log row also shows the expires_at timestamp so you can see at a glance whether the token is still redeemable.
Still Stuck? Two-Step Support Path
Most undo errors are self-explanatory once you know which of the 6 codes fired. If the pattern doesn't match any of the sections above, work through these two steps in order.
Step 1: Start with the Royal MCP Troubleshooting Guide
Royal MCP Troubleshooting — Start Here covers MCP-layer issues that can look like undo errors (e.g. tool call never reaching the server, response getting truncated in transit).
Step 2: Email priority support
If MCP-layer diagnostics look clean, email priority support from your purchase email address at support@royalplugins.com. Priority email support is included with your license — typical response within 24 hours. Never include your license key in email; we look it up from your purchase address.
- The exact error code (e.g.
undo_handler_failed) plus the full message text - The original tool name that created the token (e.g.
wc_bulk_price_update) - The
audit_idfrom the error response's structuredContent (helps us trace the original write) - Royal MCP Pro version
- Which MCP client and how the undo call was phrased
- Time elapsed between the original write and the undo attempt (rules token_expired in or out)
- Screenshot of the audit-log row for the original write with View Details expanded