Skip to content

Disabling maintenance mode makes the selected homepage private and returns 404 #523

Description

@pirate-bot

Summary

Selecting an existing published homepage as the maintenance page and then disabling maintenance mode can leave that homepage private.

Expected behavior: Disabling maintenance mode leaves an existing selected page publicly available with its prior publication state.

Actual behavior: The selected homepage becomes private. Logged-out and incognito visitors receive a 404 until the page is manually republished.

Impact: This workflow can take a site's homepage offline after maintenance mode is disabled, and deactivating LightStart does not recover the page.

Customer context

  • Product / area: LightStart, block-based maintenance page selection
  • Version: Not provided; the inspected repository is v2.6.22
  • Environment: WordPress site using an existing static homepage
  • Integration / third party: Elementor was used for the homepage and universal header
  • Reported error / symptom: The homepage became private and returned 404 to logged-out/incognito visitors after maintenance mode was disabled; it remained private after LightStart was deactivated
  • Impact: The homepage was unavailable until manually republished

Reproduction notes

Reported and source-supported workflow:

  1. Migrate to the block-based maintenance-page experience.
  2. Select an existing published homepage in Design > Select page.
  3. Enable maintenance mode, then disable it.
  4. Load another request so the disabled-mode init callback runs.
  5. View the homepage while logged out or in an incognito window.

Reported result: the homepage returns 404 and is marked private; deactivating LightStart does not restore it. Manually republishing the page restores access.

Local runtime reproduction was not performed. Exact product and environment versions are missing.

Diagnosis

Conclusion

The defect is confirmed for the inspected published-page path. The customer reported that the selected homepage became private after maintenance mode was disabled, and the current code explicitly changes the configured maintenance page from publish to private whenever LightStart loads with maintenance mode disabled. No original status is recorded, and plugin deactivation only performs cache cleanup.

Where this likely occurs

  • Maintenance-page selector: views/settings.php — settings view approx. lines 219–231. wp_dropdown_pages() offers both published and private existing pages, so a site's real published homepage is a valid selection.
  • Selection persistence: includes/classes/wp-maintenance-mode-admin.phpWP_Maintenance_Mode_Admin::select_page() lines 678–699. The selected page ID is saved and the maintenance template is assigned; the page's prior publication state is not recorded.
  • Status lifecycle: includes/classes/wp-maintenance-mode.phpWP_Maintenance_Mode::__construct() lines 89–106 and 143–160. Active mode publishes a selected private page; disabled mode registers an init callback that changes a selected published page to private.
  • Plugin deactivation: includes/classes/wp-maintenance-mode.phpWP_Maintenance_Mode::deactivate() lines 394–410 and WP_Maintenance_Mode::single_deactivate() lines 673–675. The deactivation flow reaches cache cleanup only and does not restore page status.
  • Git history: commit 73707a4777dfb54f4fb7932b664f5347c8134927 introduced the automatic status lifecycle, and commit ad60450bdaa9efc73265e5137dbaf12a4fabe7df moved the disable-side private transition to init. The behavior is present from v2.5.0 through the inspected v2.6.22.

Engineering notes

The same selector supports plugin-oriented maintenance pages and pre-existing site pages, but the inspected status lifecycle treats the selected ID as a maintenance asset regardless of its original role. This creates a data-lifecycle boundary between generated maintenance pages and customer-owned published pages. Direct plugin deactivation differs from disabling maintenance mode: deactivation does not itself make a page private, but it also does not recover a page already privatized by the disabled-mode request. The reported Elementor header omission is not required to establish the status defect and may be a separate template behavior. Multisite cleanup is routed through the same cache-only single_deactivate() method, but multisite reproduction was not performed.

Test coverage status

tests/generic-test.phpTest_Generic lines 9–39 covers constants, helper behavior, class loading, and banners only. No relevant coverage was found during inspection for selecting an existing page, preserving publication state, enable/disable transitions, or plugin deactivation.

What to verify or explore next

  • May be worth reproducing on v2.6.22 with a static published homepage selected through Design > Select page, followed by enabling and disabling maintenance mode.
  • May be worth confirming the resulting post status and logged-out homepage response after the next init request and after plugin deactivation.
  • Compatibility checks could cover a plugin-generated maintenance page, a customer-owned non-home page, direct plugin deactivation while mode is active, multisite activation, and Elementor versus the block editor.
  • If regression tests are added later, the existing WordPress PHPUnit suite can exercise status transitions around WP_Maintenance_Mode initialization.

Unknowns / follow-up

  • The customer's exact LightStart, WordPress, PHP, theme, and Elementor versions were not provided.
  • No local runtime reproduction was performed; confirmation combines the customer's observed private status with the explicit reachable repository branch.
  • WordPress core source was not present in the inspected plugin checkout, so broader core behavior beyond the plugin's direct status-update calls was not independently inspected.

Confidence

Confidence: 97/100

The customer observed the selected homepage become private, and repository inspection confirms a reachable disable-mode branch that performs exactly that status transition without preserving or restoring the original state. The behavior is deterministic for the inspected published-page path and is not covered by existing tests.


Source: HelpScout #3388512595
Generated by bug-report-triage (ID: bug-report-triage_6a58c7d6ab75a1.93454547)

Metadata

Metadata

Assignees

Labels

bug-reportbug-report-triagecustomer reportIndicates the request came from a customer.releasedIndicate that an issue has been resolved and released in a particular version of the product.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions