Skip to content

Markdown Feeds: Rebuild rewrite rules when they are missing the feed - #1110

Merged
dkotter merged 3 commits into
WordPress:developfrom
ekamran:shifteq/markdown-feeds-stale-rewrite-rules
Oct 5, 2026
Merged

dkotter merged 3 commits into
WordPress:developfrom
ekamran:shifteq/markdown-feeds-stale-rewrite-rules

Conversation

@ekamran

@ekamran ekamran commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

What?

Closes #1109

Makes the Markdown Feeds experiment rebuild the rewrite rules when its feed is registered but the stored rules do not list it, so the advertised /feed/markdown/ URL no longer returns 404.

Why?

The experiment schedules a rewrite rules flush only when its enabled option is added or updated. When the rules are rebuilt while the feed is not registered (the plugin was inactive during a flush, or wp rewrite flush --skip-plugins), or when the experiment is enabled with the wpai_feature_markdown-feeds_enabled filter, the stored rules do not list the feed and nothing adds it back. /feed/markdown/ and the per-archive feeds return 404 while the page head still advertises the feed. Steps and details are in #1109.

How?

  • maybe_flush_rewrite_rules() keeps the scheduled flush as it is. It now also flushes when the feed is registered with WordPress but no root feed rule in the stored rules lists it.
  • The check runs on wp_loaded, before the request is routed. So the first request after the rules went stale is already served correctly, even when that request is the feed itself.
  • Only the missing direction is repaired. A rule left behind while the feed is not registered is not removed, because that URL is a 404 either way. This also means a filter that enables the experiment for some request types only cannot make the rules rebuild back and forth.
  • If a flush does not bring the feed back, because something else keeps it out of the rules, a one hour transient stops further attempts so the rules are not rebuilt on every request. A flush scheduled by the toggle does not wait for it, and a flush that brings the feed back ends the wait.
  • Plain permalinks, and rule sets without a standard root feed rule, are left alone.
  • Cost of the check per request: about 5 microseconds on a default site (97 rules) and about 0.14 ms with 3,097 rules, measured on PHP 8.5. Almost all of it is get_option( 'rewrite_rules' ). While the experiment is off, the check returns before reading the option.
  • Adds one sentence about this to docs/experiments/markdown-feeds.md.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code and Codex
Used for: Investigation, implementation, tests, verification harness, and PR wording. I reviewed the reasoning and test results, and I take responsibility for the contribution.

Testing Instructions

  1. Use any permalink structure other than Plain. Enable the Markdown Feeds experiment under Settings > AI and confirm that /feed/markdown/ shows the feed.
  2. Deactivate the AI plugin, click Save Changes on Settings > Permalinks, and activate the plugin again.
  3. Open /feed/markdown/. On develop it is the 404 page. With this PR it shows the feed.
  4. Optional: run wp rewrite flush --skip-plugins and open /feed/markdown/ again. Same result.
  5. Optional: switch the experiment off, load any page once, then enable it with add_filter( 'wpai_feature_markdown-feeds_enabled', '__return_true' ); in a small plugin. Same result.

Automated:

  • npm run test:php -- --filter Markdown_ passes with 41 tests and 85 assertions. Eleven tests are new. Five of them fail on develop and pass here. The other six check that nothing is flushed when it should not be.
  • The same group passes with WP_MULTISITE=1.
  • The full PHP suite passes on single site and on multisite (1744 tests).
  • composer lint and PHPStan pass.

Also verified by hand in wp-admin on a local WordPress 7.1 site with steps 1 to 3, before and after. Steps 4 and 5, five permalink structures and plain permalinks were verified with scripted requests, before and after.

Changelog Entry

Fixed - Markdown Feeds: the feed URL no longer returns 404 when the rewrite rules were rebuilt without the feed.

Open WordPress Playground Preview

The experiment only scheduled a rewrite rules flush when its enabled option
was added or updated. When the rules were rebuilt while the feed was not
registered (the plugin was inactive during a flush, or the flush ran with
plugins skipped), or when the experiment was enabled by filter, the stored
rules did not list the feed and nothing added it back. /feed/markdown/
returned 404 while the page head still advertised it.

maybe_flush_rewrite_rules() now also flushes when the feed is registered but
no root feed rule in the stored rules lists it. A flush that does not bring
the feed back is not repeated for an hour.
@ekamran
ekamran requested a review from a team October 5, 2026 08:58
@ekamran
ekamran requested a review from jeffpaul as a code owner October 5, 2026 08:58
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: ekamran <ekamran@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
Co-authored-by: rahultank-spaceo <rahultank@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@codecov

codecov Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.58%. Comparing base (aabe57e) to head (b6ed961).

Additional details and impacted files
@@              Coverage Diff              @@
##             develop    #1110      +/-   ##
=============================================
+ Coverage      81.55%   81.58%   +0.02%     
- Complexity      3074     3081       +7     
=============================================
  Files            129      129              
  Lines          12261    12275      +14     
=============================================
+ Hits           10000    10015      +15     
+ Misses          2261     2260       -1     
Flag Coverage Δ
unit 81.58% <100.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rahultank-spaceo

Copy link
Copy Markdown

Test Report

Patch tested: #1110 (commit f88a8d2), compared with develop (f52eb36)

Environment

  • WordPress: 7.1.2 (WordPress Playground)
  • PHP: 8.3
  • Plugin: AI, built from source (npm ci && npm run build)
  • Browser: Google Chrome 153.0.8010.52
  • OS: Linux
  • Theme: Twenty Twenty-Five
  • Permalinks: /%year%/%monthnum%/%day%/%postname%/

Steps

  1. Enabled the Markdown Feeds experiment and confirmed /feed/markdown/ works.
  2. Deactivated the AI plugin, saved Settings → Permalinks, and activated the plugin again (steps from Markdown Feeds: /feed/markdown/ returns 404 after the rewrite rules are rebuilt without the feed #1109).
  3. Requested the feed URLs and checked the text/markdown link tag on the home page.
  4. Repeated the same steps with the PR applied.

Results

URL develop PR #1110
/feed/markdown/ 404 ❌ 200 text/markdown ✅
/category/uncategorized/feed/markdown/ 404 ❌ 200 text/markdown ✅
/?feed=markdown 200 200
  • After the flush without the plugin, the stored root feed rule was feed/(feed|rdf|rss|rss2|atom)/?$ (no markdown) on both branches. With the PR, the first front-end request served the feed correctly.
  • On develop the home page still advertised /feed/markdown/ in the text/markdown link tag while that URL was a 404.

✅ The patch fixes #1109.

@dkotter dkotter added this to the 1.4.0 milestone Oct 5, 2026
@dkotter
dkotter merged commit f3f2bd2 into WordPress:develop Oct 5, 2026
36 checks passed
@ekamran
ekamran deleted the shifteq/markdown-feeds-stale-rewrite-rules branch October 5, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Markdown Feeds: /feed/markdown/ returns 404 after the rewrite rules are rebuilt without the feed

3 participants