There is no problem not worth solving, and no technology not worth learning!

Reinstalling Yoast SEO Broke an Old Post: Debugging a WordPress Fatal Error Caused by a Duplicate WPCode Snippet Function

【图5:旧文章打开时出现 WordPress 致命错误】

作者:

Blog SEO Log

收到 Google Search Console 的邮件:新原因导致网站 http://www.shuijingwanwq.com/ 上的网页无法被编入索引。如图1

(1) Google webpage cannot be indexed? I solved it like this

验证通过后,在左侧菜单找到「站点地图」,输入 `/wp-sitemap.xml`,点击提交即可(如图1)

(2) Five search engine site map submissions full record: from Google to Sogou, my practical experience to share

sitemap采用邀请制,当您的网站存在原创或不可替代内容或不能被搜狗spider正确抓取时,才会开通sitemap权限。

(3) Sogou sitemap permission application record: the whole process from review to submission

所有主体、验证、备案配置全部完成后,进入核心的收录配置环节:【资源提交 - 普通收录 - 资源提交 - sitemap】,发现页面额度显示异常(如图3)

(4) Baidu search resource platform new station completes the complete collection of practical records

美国流量占 20%,日本 10%,香港 16%,台湾 9%

(5) Technical Blog English Station Index and Low Value Label Processing

中文站点地图:`https://www.你的域名.com/wp-sitemap-posts-post-1.xml` → 显示“致命错误”如图2

(6) Fixed WordPress fatal error: from sitemap error to return to normal

Bing 明确指出了 4.2K 个页面存在“内容质量”问题

(7) Blog SEO Diagnostic Records: Causes and Optimization List of Nearly 15000 Pages Not Indexed

点击表头的“总数”进行排序,数量为 0 的标签会集中在前几页。

(8) Thoroughly clear WordPress empty tags: Eliminate soft 404, save grabbing budget

/tag/bsc/ 网页源代码中成功出现 noindex 标签

(9) Blog SEO Diagnostic Records: Thin Content Tabs NoIndex Scheme Practical and Multilingual Test Validation

“0秒访问”主要来自标签页

(10) WordPress Tag SEO Optimization Practice: Use WPCode to Realize “Low Content Tab Page NoIndex” Complete Detach and Repair Records

图1:Bing整体流量趋势(下降起点)

(11) Bing Traffic Drop After Switching WordPress Themes: An Ongoing SEO Postmortem of a Site Structure Change

【图5:旧文章打开时出现 WordPress 致命错误】

(12) Reinstalling Yoast SEO Broke an Old Post: Debugging a WordPress Fatal Error Caused by a Duplicate WPCode Snippet Function

I recently reinstalled and enabled the free version of Yoast SEO. My original goal was simple: restore basic SEO features for my WordPress posts, such as SEO titles, Meta Description fields, and XML Sitemap support.

At first, everything seemed to go smoothly. After Yoast SEO was installed, WordPress showed the prompt for the first-time configuration wizard.

[Figure 1: Yoast SEO installation success page]
[Figure 1: Yoast SEO installation success page]

But during later testing, I ran into a more hidden problem:

New posts could be opened normally;

but one of my old posts immediately triggered a WordPress fatal error.

This article documents the full troubleshooting process. At first glance, the issue looked as if it was caused by Yoast SEO. In the end, however, the real cause was not Yoast itself, but a duplicated function declaration inside a custom PHP Snippet in WPCode.

1. Reinstalling Yoast SEO Free

This time, I reinstalled the free version of Yoast SEO.

After installation, Yoast prompts you to start its First-time configuration wizard.

[Figure 2: Yoast SEO first-time configuration entry point]
[Figure 2: Yoast SEO first-time configuration entry point]

In the configuration wizard, the first step is SEO data optimization. During this process, Yoast scans the existing content on the site and builds its own SEO data index.

[Figure 3: Yoast SEO running SEO data optimization]
[Figure 3: Yoast SEO running SEO data optimization]

Because my blog has a fairly large number of posts, this step took a little while.

After the optimization finished, the page displayed:

We’ve successfully analyzed your site & optimized your SEO data!

[Figure 4: Yoast SEO data optimization completed]
[Figure 4: Yoast SEO data optimization completed]

Up to this point, the installation and basic initialization of Yoast SEO itself were working properly.

2. The Symptom: New Posts Worked, but an Old Post Would Not Open

After enabling Yoast SEO, I tested a newer post:

This post opened normally.

But another old post from 2021:

triggered a WordPress fatal error.

The page showed the message:

There has been a critical error on this website.

[Figure 5: WordPress fatal error when opening an old post]
[Figure 5: WordPress fatal error when opening an old post]

This kind of symptom is easy to misread.

The reason is that the behavior looked like this:

After disabling Yoast SEO, the old post recovered;

after enabling Yoast SEO, the old post failed again;

so my first impression was that Yoast SEO might be incompatible with the structure of old posts.

But as the later logs proved, Yoast SEO was more like a trigger. It was not the root cause.

3. First Check Whether the Admin Editing Page Still Works

To determine whether the post content itself was completely corrupted, I first opened the admin editing page for that old post.

The editing page opened normally.

[Figure 6: The old post can still be opened in the admin editor]
[Figure 6: The old post can still be opened in the admin editor]

This old post used the legacy Classic Block structure, and the content also contained old caption image shortcodes.

But since the admin editor could still open the post, the post data itself was not completely broken.

The issue was more likely happening during front-end rendering.

4. Check the PHP-FPM Log to Find the Real Error

Next, I checked the PHP-FPM log through SSH on the server.

The command was:

Bash
tail -n 80 /usr/local/php/var/log/php-fpm.log

The key error appeared in the log:

Plaintext
PHP Fatal error: Cannot redeclare custom_desc_and_ads_inserter()

The more complete error information pointed to WPCode’s snippet executor:

Plaintext
wp-content/plugins/insert-headers-and-footers/includes/class-wpcode-snippet-execute.php

In other words, the code that actually caused the WordPress fatal error was not inside the Yoast SEO plugin directory. It came from a PHP Snippet executed by WPCode / Insert Headers and Footers.

The function name was also familiar:

PHP
custom_desc_and_ads_inserter()

It came from a PHP Snippet I had written earlier:

PHP Code to Replace 16 Ad Inserter Rules

The purpose of this Snippet was to automatically insert different recommendation notes, affiliate links, or technical service inquiry blocks at the bottom of posts based on conditions such as post language, series, and category.

5. Why Did New Posts Open Normally While Old Posts Failed?

This part was confusing.

If Yoast SEO itself had been broken, theoretically all posts should have failed to open.

But the actual behavior was:

New posts worked normally;

some old posts failed;

after disabling a certain WPCode Snippet, the page recovered;

after enabling the Snippet again, the error returned.

This showed that the real issue was not “Yoast SEO caused all posts to crash.” Instead, a Snippet was being loaded more than once on a specific page execution path, which eventually declared the same PHP function twice.

In PHP, a function cannot be declared more than once.

If the same request executes the following function declaration twice:

PHP
function custom_desc_and_ads_inserter() {
    // ...
}

it will trigger:

Plaintext
Cannot redeclare custom_desc_and_ads_inserter()

After Yoast SEO was enabled, the front-end rendering flow changed in some way, which probably exposed a previously hidden WPCode Snippet loading problem.

So the more accurate conclusion was:

Yoast SEO was the trigger;

the unsafe function declaration inside the WPCode Snippet was the root cause.

6. Temporary Fix: Disable the Problematic Snippet

To restore the live site first, my first step was to disable this Snippet.

The path was:

WordPress dashboard → Code Snippets → All Snippets → PHP Code to Replace 16 Ad Inserter Rules → Deactivate

After disabling it, the old post recovered.

This step mattered because when troubleshooting a live production issue, the top priority is to restore user access first, not to immediately rewrite the code.

7. First Fix Attempt: Adding a return Guard at the Top, but It Was Not Ideal

My first attempt was to add a duplicate-load guard at the top of the Snippet:

PHP
if (
    defined('SW_DESC_ADS_SNIPPET_LOADED') ||
    function_exists('custom_desc_and_ads_inserter') ||
    function_exists('custom_in_category_tree')
) {
    return;
}

define('SW_DESC_ADS_SNIPPET_LOADED', true);

The idea was:

If the function already exists, return immediately to avoid declaring it again.

But after testing, although the old post no longer consistently threw the same error, the recommendation / consultation block at the bottom of the post did not display correctly.

The reason was also clear:

This Snippet outputs its final content directly through the following line:

PHP
echo custom_desc_and_ads_inserter();

If the code returns early at the top, the output logic later in the Snippet may also be skipped.

So this approach was not a good fit for the structure of this particular Snippet.

8. Final Fix: Add function_exists Protection Around Function Declarations

A safer approach was not to return directly at the top of the Snippet, but to wrap each custom function declaration with a function_exists() check.

The original main function looked like this:

PHP
function custom_desc_and_ads_inserter() {
    // 原来的函数内容
}

I changed it to:

PHP
if (!function_exists('custom_desc_and_ads_inserter')) {
  function custom_desc_and_ads_inserter() {
      // 原来的函数内容
  }
}

The helper function originally looked like this:

PHP
function custom_in_category_tree($cat_slug) {
    // 原来的函数内容
}

I changed it to:

PHP
if (!function_exists('custom_in_category_tree')) {
  function custom_in_category_tree($cat_slug) {
      // 原来的函数内容
  }
}

With this change, even if WPCode loads the same Snippet more than once during certain requests, it will not try to redeclare an existing function.

At the same time, the output logic at the end of the code can still be kept:

PHP
echo custom_desc_and_ads_inserter();

This was a better fit for this Snippet than returning directly at the top.

9. Re-enable the Snippet and Test Again

After making the change, I re-enabled the Snippet.

Then I tested the following:

whether the old post page could open normally;

whether the recommendation / consultation block at the bottom displayed correctly;

whether the new post page could open normally;

whether the bottom block on the new post displayed correctly.

The test results were:

The old post opened normally;

the bottom block on the old post displayed correctly;

the new post opened normally;

the bottom block on the new post displayed correctly;

there were no new Fatal error entries in the PHP-FPM log.

[Figure 7: The old post page is working again]

[Figure 7: The old post page is working again]
[Figure 8: The recommendation / consultation block at the bottom displays correctly]
[Figure 8: The recommendation / consultation block at the bottom displays correctly]

10. Complete the Yoast SEO First-time Configuration

After confirming that the fatal error had been fixed, I continued with the Yoast SEO first-time configuration.

The Yoast SEO first-time configuration mainly includes the following steps:

SEO data optimization;

Site representation;

Social profiles;

Preferences;

Finish configuration.

In the Site representation step, I selected “Person”.

[Figure 9: Yoast SEO Site representation settings]
[Figure 9: Yoast SEO Site representation settings]

For Social profiles, I did not add anything for the moment. I can complete that later if needed.

[Figure 10: Yoast SEO Social profiles settings]
[Figure 10: Yoast SEO Social profiles settings]

In Preferences, I did not subscribe to emails, and I also chose not to share site data.

[Figure 11: Yoast SEO Preferences settings]
[Figure 11: Yoast SEO Preferences settings]

Finally, Yoast SEO showed that the configuration was complete.

[Figure 12: Yoast SEO first-time configuration completed]
[Figure 12: Yoast SEO first-time configuration completed]

11. Check the Yoast SEO Dashboard and Alert Center

After finishing the setup, I opened the Yoast SEO dashboard.

There were some promotional prompts for Yoast SEO Premium, Site Kit, and SEO Task list in the middle of the page. These were not things I had to deal with right away.

The part that really mattered was the Alert center.

The Alert center showed:

Problems: 0;

Notifications: 0.

[Figure 13: Yoast SEO Alert center showing 0 problems]
[Figure 13: Yoast SEO Alert center showing 0 problems]

This means Yoast did not detect any serious SEO configuration issue at that point.

12. Verify XML Sitemap and robots.txt

After installing an SEO plugin, one of the most important basic checks is the XML Sitemap.

I opened:

Plaintext
https://www.shuijingwanwq.com/sitemap_index.xml

The page correctly displayed the sitemap index generated by Yoast SEO.

[Figure 14: Yoast SEO XML Sitemap generated correctly]
[Figure 14: Yoast SEO XML Sitemap generated correctly]

Then I continued checking robots.txt:

Plaintext
https://www.shuijingwanwq.com/robots.txt

The content included:

Plaintext
Sitemap: https://www.shuijingwanwq.com/sitemap_index.xml
[Figure 15: robots.txt correctly declares the sitemap URL]
[Figure 15: robots.txt correctly declares the sitemap URL]

This means search engines can find the XML Sitemap generated by Yoast through robots.txt.

13. Clear the Cache at the End

After completing the configuration and the fix, I purged all caches through W3 Total Cache.

The path was:

WordPress top admin bar → Performance → Purge All Caches

[Figure 16: Purging all caches in W3 Total Cache]
[Figure 16: Purging all caches in W3 Total Cache]

After clearing the cache, I verified the front-end pages again and confirmed that the old post, the new post, the bottom blocks, and Yoast SEO were all working normally.

14. What I Learned from This Troubleshooting Case

On the surface, this issue looked like:

After enabling Yoast SEO, old posts could no longer be opened.

But after troubleshooting, the real cause was:

A PHP Snippet in WPCode redeclared the custom_desc_and_ads_inserter() function, which caused a PHP Fatal error.

Yoast SEO only exposed this hidden issue. It was not the root cause.

A safer troubleshooting process is:

Do not rush to uninstall Yoast;

first disable the suspicious Snippet and check whether the page recovers;

check the PHP-FPM log and find the real Fatal error;

add function_exists() duplicate-declaration protection to custom PHP functions;

re-enable the Snippet and verify both the front-end page and the PHP log;

clear the cache at the end.

15. What to Watch Out for When Writing WPCode Snippets in the Future

This issue also reminded me to build a few better habits when writing PHP Snippets in WPCode.

First, custom functions should use unique prefixes whenever possible.

For example, avoid overly generic function names like this:

PHP
function custom_desc_and_ads_inserter() {
}

A better approach is to use a more specific prefix:

PHP
function shuijingwan_custom_desc_and_ads_inserter() {
}

Second, add a function_exists() check before declaring a function.

For example:

PHP
if (!function_exists('shuijingwan_custom_desc_and_ads_inserter')) {
  function shuijingwan_custom_desc_and_ads_inserter() {
      // ...
  }
}

Third, when troubleshooting plugin conflicts on a live site, do not rely only on surface-level symptoms.

In this case, the visible behavior could easily have made me think Yoast SEO was the problem.

But the key error in the log was not inside the Yoast plugin directory. It was inside WPCode’s Snippet executor.

So when WordPress reports a fatal error, the PHP log is often much more useful than the generic error message shown in the dashboard or on the front end.

Conclusion

Reinstalling Yoast SEO took more time than I expected this time.

But the final result was good:

Yoast SEO Free is now enabled normally;

the first-time configuration is complete;

XML Sitemap is generated correctly;

robots.txt correctly declares the sitemap;

the old-post access issue has been fixed;

the recommendation / consultation block at the bottom of posts from the WPCode Snippet is also showing again;

there are no new Fatal error entries in the PHP-FPM log.

For a WordPress blog that has been running for many years, re-enabling an SEO plugin, recovering old SEO data, and making it work with historical posts and existing custom code can easily reveal hidden problems.

This troubleshooting process turned into a typical WordPress plugin conflict case: do not judge only by which plugin was just enabled. Use the logs to find the exact code location that is really throwing the error.

Bing Traffic Drop After Switching WordPress Themes: An Ongoing SEO Postmortem of a Site Structure Change

WordPress Maintenance, Performance Optimization & Blog Growth Consulting

I have been running my personal technology blog for more than 10 years and have published over 1,000 original articles. My long-term practice covers WordPress website maintenance, CDN / Cloudflare configuration, caching optimization, Google SEO, ad monetization, and multilingual website operations.

If your WordPress website is slow, unstable, affected by plugin conflicts, showing caching issues, having AdSense display problems, or facing CDN / Cloudflare / DNS configuration uncertainty, feel free to contact me for remote troubleshooting.

Ideal For:
✅ Personal blog owners
✅ WordPress website operators
✅ Independent developers and content creators
✅ SaaS website owners
✅ Website owners who want better speed and stability

What I Offer:
✅ WordPress performance optimization
✅ Cloudflare / CDN / caching configuration checks
✅ Plugin conflict and layout issue troubleshooting
✅ AdSense display issue troubleshooting
✅ Basic SEO structure review
✅ Blog growth and monetization consulting

If you would like to discuss your website, please contact me and mention: WordPress Maintenance Consultation.

Contact Me:
Telegram: @shuijingwan
WeChat: 13980074657
Email: shuijingwanwq@gmail.com

评论

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.