Troubleshooting Programmatic SEO and AI
9 min read
Start with the task card on the Programmatic SEO screen (status, counters, notice), then the SEO health card on the task's Pages screen, then WPM Fields › Settings › Health for logged errors. This page lists the usual symptoms.
Pages
A generated URL shows a 404
Work down this list:
Check | How |
|---|---|
Does the page exist? | Task › Pages, search the URL. No row means the run has not created it (paused task, filter, rule or limit, see "Fewer pages than rows"). |
Status Hidden | Hidden pages answer 404. Click Show. |
Status Removed | Its row is gone or filtered out; removed pages answer 410 (or redirect). |
Status URL in use | Real content uses the URL and is shown instead (Serving pages). |
The path differs from what you expect | Compare with the Preview of the URL step. Accents, case, spaces and |
Permalinks | Generated pages need a pretty permalink structure (not Plain). |
License | After the 14-day grace period of an expired license, or after a trial, pages are no longer served (Limits and plans). |
Plugin deactivated | Serving stops while the plugin is off; pages return when it is active. |
Page cache | An old 404 or old page may be cached; clear the cache (Freshness and caches). |
A | Paged requests are never served. |
The page looks different from the template (missing styles)
Generated pages use your theme and the template's content. Page builder CSS and scripts are loaded for Elementor and Avada; other builders may need their "render by post ID" features that depend on a real post (the page uses the template's post ID). Open a generated page and view source: if the template's CSS file is missing, edit the template once in the builder and save it (this also clears caches), then purge your cache. Report builders that still fail.
I see {{ pseo.src.… }} on the page
- You are looking at the template page itself, which shows the raw placeholders. Only generated URLs resolve them.
- The source key or column name is wrong: it must match exactly (
{{ pseo.src.cities.name }}, lowercase, no spaces in the name). A wrong name resolves to nothing, not to the text. Use the variable chips. - Variables written with a builder widget that escapes braces: check the widget's setting for dynamic content or use a text/HTML block.
- The text comes from a field value that was set by hand with the braces in a place that is not resolved (a plain field you edited on the page, a post title). Variables resolve in the template content, template field values, and the patterns of the task.
Parts are empty or show the wrong values
- A number column prints its stored decimals (
1234.500000); use| number(2). - A function without
fn.prints nothing:{{ fn.year() }}is right,{{ year() }}is not. ({{ fn.now() | date("Y") }}prints the year.) - An unknown filter name does nothing:
number_formatis not a filter,number(2)is. - A column holds HTML with tags WordPress does not allow in posts: those tags are removed.
- The page shows the template's field value instead of mine: check that the field is read through the shortcode or block, not typed into the template's text. Hand-set values win, then AI values, then the template's own value (Templates and field values).
Fewer pages than rows
Open the card's last run: created, updated, removed, conflicts, shadowed, limited. Then:
Cause | Sign | Fix |
|---|---|---|
Filters leave rows out | Preview total is lower | Review the conditions (Data sources) |
A quality rule says "create no page" | Rows with empty values missing | Change or remove the rule (SEO plugins and meta) |
The URL resolves to nothing | Rows with an empty column used in the URL | Fill the data or use |
Duplicate URLs (conflicts) | "%s row skipped: another generated page uses its URL." | Make the URL unique |
URL in use (shadowed) | "%s page offline: WordPress content uses its URL." | Change the pattern or the real slug |
Page limit | "%s page waits for the page limit." | Delete pages or upgrade |
Daily limit | Waiting, "Daily page limit reached. New pages follow tomorrow." | Wait or raise New pages per day |
Languages with Skip the page in that language | Language pages missing for rows without translations | Fill the |
Row mode keeps one source | A second source ignored | Use combination mode (Business) |
Pages were deleted when I saved the task
Saving a task with different sources or another mode resets its pages (the editor warns). Changes to filters, patterns or SEO do not.
Old URLs of renamed pages still show something
They redirect (301) to the new URL on purpose. A converted page redirects to its post.
A URL contains %cc%87 or an extra folder
İstanbul | lower leaves an encoded combining dot, and / in data creates extra path segments. Use | slug or the plain value (URL and title patterns).
Running
The run never starts ("Waiting for the background runner to start…", the task stays Generating with no progress)
Background jobs need something to trigger WordPress. Visit the site (WP-Cron runs on visits), or run the queue with wp action-scheduler run --group=wpmcf, or set up a system cron (see Background tasks and WP-CLI). If DISABLE_WP_CRON is set, a system cron is required. A security plugin or a host that blocks wp-cron.php has the same effect. Check Tools › Scheduled Actions for pending wpmcf actions.
The task shows Failed
The card shows the error. Fix the cause (template deleted, source deleted, database error) and click Run now. After three failures in a row the task stops by itself (Background tasks).
The task shows Waiting
It finished and has a notice (limit reached, shadowed pages, a missing plugin). The card says which; see Running and scheduling.
Data changed but pages did not
- The task is paused (paused tasks never run from data changes).
- Update pages when the data changes is off.
- The source is a field group table (no automatic updates).
- The change was made directly in the database with SQL, which bypasses the events the plugin listens to; click Run now.
- A page cache serves the old page.
The Programmatic SEO menu is missing or shows "Your license has expired"
Without Pro the screen does not exist (Pro page instead). With an expired license it is replaced by the expiry screen with Renew license and Convert pages to posts (Limits and plans).
Search engines and SEO plugins
Every page has the same title or description as the template
An SEO plugin that is not supported (SEOPress, The SEO Framework, Slim SEO…) prints the template's values; the SEO health says "Your SEO plugin is not supported for generated pages…". Use Yoast SEO, Rank Math or All in One SEO, or no SEO plugin (SEO plugins and meta).
Yoast, Rank Math or AIOSEO output does not show my values
These integrations use the plugins' public hooks and were not verified on live installs for this documentation. Check: the plugin is up to date, its title and description templates for the post type of your pages, that no other plugin overrides its output. In Yoast the title format is the plugin's template for the post type; with Use the SEO title exactly as written the SEO title is used as is.
Pages are indexed but should not be, or the other way round
- The task's Show pages in search results, quality rules and a page's own Show this page in search results decide noindex. Hand settings win.
- The robots decision is stored at run time: run the task after changing indexing settings.
- Discourage search engines from indexing this site (Settings › Reading): generated pages carry WordPress’s
noindex, nofollowlike normal pages, whatever the task or the page says. Turn the setting off when the site goes live.
Pages are not in the sitemap
Only live, indexable pages of tasks with List pages in the sitemap on are listed, while the license allows generation; shadowed pages are left out (Sitemaps). Check /wp-sitemap.xml for wp-sitemap-pseo-1.xml. If an SEO plugin disabled the core sitemap, look in its own sitemap index (Yoast: pseo-sitemap.xml).
Structured data is missing
- The step Structured data is off or no type is added.
- A JSON-LD template with invalid JSON prints nothing ("The structured data template of “…” is not valid JSON" in Settings › Health).
- Required properties are empty: the preview reports them.
- The SEO plugin graph replaced the markup: leave Replace the SEO plugin’s article markup on.
Several hreflang sets or wrong switcher links
On multilingual tasks the plugin suppresses WPML's and Polylang's own hreflang for generated pages. If you still see duplicates, an SEO plugin prints its own; check the checklist in Multilingual pages.
AI
"Add an API key in Settings › AI" or No API key yet
The key for the selected provider is missing. Keys are per provider: choose the provider first, then save its key (AI setup).
Connection failed
Read the provider's message: wrong key, no credit, rate limit, model not available for your account (use Refresh list). Save the provider and model before testing.
"The saved key can no longer be read"
The site's security salts changed since the key was saved. Enter the key again, or define it in wp-config.php.
The run stops at once
See the panel's notice. Typical: key rejected, quota exhausted, or "There is nothing for AI to write: assign a field group to the template, or map SEO or structured data values to AI." (Write field content with AI is off or no field group matches the template or every field has Write this field off, and SEO and structured data AI are off).
AI content is written but not visible
- The template does not print the field (
[wpmcf_field], block or a builder tag). The page shows the field only where the template reads it. - The value is Waiting for AI or AI failed: see the page editor.
- The SEO title or description: the task's Let AI write … switch is off (the value exists but is ignored), or a hand-set value wins.
- Caches: purge.
"The AI answer was cut off at the maximum answer length"
Raise Maximum answer length (tokens) in Settings › AI, or reduce the fields per page. Cut-off answers are not asked again in the same run.
A rate limit keeps pausing the run
Lower Requests per minute below your provider's limit. After 10 limits in a row the run stops.
The bill is larger than expected
Changing the brief or the data makes values outdated and the next run rewrites them; Rewrite all… rewrites everything. See AI privacy and costs.
Conversion
Problem | Cause and fix |
|---|---|
No Convert button on a card | Read the message under the card: post type gone, no live pages, or above the limit |
"Your plan allows converting %d more pages…" | The conversion cap counts all pages converted so far. Convert fewer pages (hide some) or upgrade. |
Old URL does not redirect | Only pages whose permalink changed redirect; a page with the same URL is simply the post |
Posts have the template's layout but no AI values | AI values convert only when they exist before converting; run AI first |
Converted again by mistake | Conversion never duplicates: a converted page stays linked to its post |
Still stuck?
Collect the task's last run counters, the SEO health result, the entry in Settings › Health and the exact URL, and contact support from the plugin's Support link.
Still stuck? Contact support