Prerequisites
Please give us a description of what happened
Plugin version: Yoast SEO 27.2
WordPress version: 6.9.4
PHP version: 8.3.6
Theme: Salient 18.0.2
Table prefix: non-standard (abc_ instead of wp_)
Summary
When "Index your content" runs from WP Admin → Yoast SEO → Tools, the batch indexer writes the URL of the page currently loaded in the browser as the permalink value in yoast_indexable for every post processed in the batch — instead of each post's actual permalink.
Steps to Reproduce
- Have a site with published posts using a custom table prefix.
- Navigate to WP Admin → Yoast SEO → Tools → Index your content.
- Run the indexer to completion.
- Query the indexable table:
SELECT object_id, permalink FROM {prefix}yoast_indexable WHERE object_type='post' LIMIT 20
Expected: Each row's permalink matches that post's actual URL (as returned by get_permalink($object_id)).
Actual: Every post processed in the batch has an identical permalink value — the URL of the admin page (or whatever URL was "current" during the AJAX run).
Reproduction Confirmed Twice, With Different Poison URLs
- Run 1: Indexer triggered while
/affiliate-disclosure/ was the last non-admin page visited. All 28 affected posts received permalink = https://example.com/affiliate-disclosure/.
- Run 2: Indexer triggered while
/about/ was in context. Same 28 posts received permalink = https://example.com/about/.
Both runs were confirmed by querying the yoast_indexable table directly before and after. The canonical column is NULL on all affected rows — meaning the permalink column is what Yoast uses to generate the <link rel="canonical"> tag and all schema @id values.
Impact
- Every post affected outputs the wrong URL in
<link rel="canonical">, <meta property="og:url">, and the entire JSON-LD schema graph (Article @id, WebPage @id, BreadcrumbList @id, ReadAction target).
- Google is told all affected posts are duplicates of whichever page happened to be "current" when the indexer ran.
- The
canonical column in the indexable is NULL (no user override), so there is no post-level meta to fall back to. The bad permalink value is authoritative.
Workaround: Delete the affected rows from yoast_indexable. Yoast's lazy rebuild on first page request generates the correct permalink. The bug only manifests when the batch indexer runs.
Likely Cause
The batch indexer processes posts via REST API AJAX calls. The permalink resolution for each post appears to be picking up the URL from the HTTP request context (referrer, $_SERVER['REQUEST_URI'], or similar) rather than calling get_permalink($post_id) in a clean per-post context. The result is that all posts in a batch share a single URL — whichever URL was active when the AJAX request was initiated.
Step-by-step reproduction instructions
Reproduction confirmed twice, with different poison URLs
Both runs were confirmed by querying the yoast_indexable table directly before and after. The canonical column
is NULL on all affected rows — meaning the permalink column is what Yoast uses to generate the tag and all schema @id values.
Steps to reproduce
- Have a site with published posts using a custom table prefix.
- Navigate to WP Admin → Yoast SEO → Tools → Index your content.
- Run the indexer to completion.
- Query the indexable table: SELECT object_id, permalink FROM {prefix}yoast_indexable WHERE object_type='post'
LIMIT 20
Expected results
- Impact
- Every post affected outputs the wrong URL in , , and the entire
JSON-LD schema graph (Article @id, WebPage @id, BreadcrumbList @id, ReadAction target).
- Google is told all affected posts are duplicates of whichever page happened to be "current" when the indexer
ran.
- The canonical column in the indexable is NULL (no user override), so there is no post-level meta to fall back
to. The bad permalink value is authoritative.
Workaround: Delete the affected rows from yoast_indexable. Yoast's lazy rebuild on first page request generates
the correct permalink. The bug only manifests when the batch indexer runs.
Actual results
Impact
- Every post affected outputs the wrong URL in , , and the entire
JSON-LD schema graph (Article @id, WebPage @id, BreadcrumbList @id, ReadAction target).
- Google is told all affected posts are duplicates of whichever page happened to be "current" when the indexer
ran.
- The canonical column in the indexable is NULL (no user override), so there is no post-level meta to fall back
to. The bad permalink value is authoritative.
Workaround: Delete the affected rows from yoast_indexable. Yoast's lazy rebuild on first page request generates
the correct permalink. The bug only manifests when the batch indexer runs.
Screenshots, screen recording, code snippet
No response
Which editor is affected (or editors)
Which browser is affected (or browsers)
Device you are using
No response
Operating system
No response
PHP version
8.3.6
WordPress version
6.9.4
WordPress Theme
Salient 18.0.2
Yoast SEO version
27.2
Gutenberg plugin version (if relevant)
No response
Elementor plugin version (if relevant)
No response
Classic Editor plugin version (if relevant)
No response
Relevant plugins in case of a bug
No response
Prerequisites
Please give us a description of what happened
Plugin version: Yoast SEO 27.2
WordPress version: 6.9.4
PHP version: 8.3.6
Theme: Salient 18.0.2
Table prefix: non-standard (abc_ instead of wp_)
Summary
When "Index your content" runs from WP Admin → Yoast SEO → Tools, the batch indexer writes the URL of the page currently loaded in the browser as the permalink value in
yoast_indexablefor every post processed in the batch — instead of each post's actual permalink.Steps to Reproduce
Expected: Each row's permalink matches that post's actual URL (as returned by
get_permalink($object_id)).Actual: Every post processed in the batch has an identical permalink value — the URL of the admin page (or whatever URL was "current" during the AJAX run).
Reproduction Confirmed Twice, With Different Poison URLs
/affiliate-disclosure/was the last non-admin page visited. All 28 affected posts receivedpermalink = https://example.com/affiliate-disclosure/./about/was in context. Same 28 posts receivedpermalink = https://example.com/about/.Both runs were confirmed by querying the
yoast_indexabletable directly before and after. Thecanonicalcolumn is NULL on all affected rows — meaning thepermalinkcolumn is what Yoast uses to generate the<link rel="canonical">tag and all schema@idvalues.Impact
<link rel="canonical">,<meta property="og:url">, and the entire JSON-LD schema graph (Article@id, WebPage@id, BreadcrumbList@id, ReadActiontarget).canonicalcolumn in the indexable is NULL (no user override), so there is no post-level meta to fall back to. The badpermalinkvalue is authoritative.Workaround: Delete the affected rows from
yoast_indexable. Yoast's lazy rebuild on first page request generates the correct permalink. The bug only manifests when the batch indexer runs.Likely Cause
The batch indexer processes posts via REST API AJAX calls. The permalink resolution for each post appears to be picking up the URL from the HTTP request context (referrer,
$_SERVER['REQUEST_URI'], or similar) rather than callingget_permalink($post_id)in a clean per-post context. The result is that all posts in a batch share a single URL — whichever URL was active when the AJAX request was initiated.Step-by-step reproduction instructions
Reproduction confirmed twice, with different poison URLs
posts received permalink = https://example.com/affiliate-disclosure/.
https://example.com/about/.
Both runs were confirmed by querying the yoast_indexable table directly before and after. The canonical column
is NULL on all affected rows — meaning the permalink column is what Yoast uses to generate the tag and all schema @id values.
Steps to reproduce
LIMIT 20
Expected results
JSON-LD schema graph (Article @id, WebPage @id, BreadcrumbList @id, ReadAction target).
ran.
to. The bad permalink value is authoritative.
Workaround: Delete the affected rows from yoast_indexable. Yoast's lazy rebuild on first page request generates
the correct permalink. The bug only manifests when the batch indexer runs.
Actual results
Impact
JSON-LD schema graph (Article @id, WebPage @id, BreadcrumbList @id, ReadAction target).
ran.
to. The bad permalink value is authoritative.
Workaround: Delete the affected rows from yoast_indexable. Yoast's lazy rebuild on first page request generates
the correct permalink. The bug only manifests when the batch indexer runs.
Screenshots, screen recording, code snippet
No response
Which editor is affected (or editors)
Which browser is affected (or browsers)
Device you are using
No response
Operating system
No response
PHP version
8.3.6
WordPress version
6.9.4
WordPress Theme
Salient 18.0.2
Yoast SEO version
27.2
Gutenberg plugin version (if relevant)
No response
Elementor plugin version (if relevant)
No response
Classic Editor plugin version (if relevant)
No response
Relevant plugins in case of a bug
No response