Skip to content

Fix crash when WordPress falls back to FTP filesystem#2974

Merged
pfefferle merged 7 commits intotrunkfrom
fix/filesystem-graceful-failure
Feb 25, 2026
Merged

Fix crash when WordPress falls back to FTP filesystem#2974
pfefferle merged 7 commits intotrunkfrom
fix/filesystem-graceful-failure

Conversation

@pfefferle
Copy link
Member

Fixes #2972

Proposed changes:

  • Centralize filesystem access in Cache\File with get_filesystem() and delete_directory() helpers that properly handle WP_Filesystem() failure (returns false but still sets $wp_filesystem to a broken FTP object).
  • Add a per-request failure flag to skip repeated initialization attempts.
  • Remove duplicated filesystem code from Cache\Media (cache_url() method) by using inherited get_or_cache().
  • Add a Site Health warning when direct filesystem access is unavailable, guiding admins to fix the issue or disable caching via ACTIVITYPUB_DISABLE_REMOTE_CACHE.

Other information:

  • Have you written new tests for your changes, if applicable?

Testing instructions:

  • Verify all existing tests pass: npm run env-test
  • Check Site Health page shows "Filesystem access is available for media caching" as good status.
  • To simulate the failure: temporarily add define( 'FS_METHOD', 'ftpext' ); to wp-config.php — Site Health should show a "recommended" warning with instructions.

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch

Type

  • Fixed - for any bug fixes

Message

Fix a crash on servers where WordPress uses FTP instead of direct file access for media caching.

Centralize filesystem access in Cache\File with get_filesystem() and
delete_directory() helpers. The core fix: WP_Filesystem() can return
false on failure but still set $wp_filesystem to a broken FTP object.
The new helper checks the return value and nulls the global on failure,
preventing fatal errors from calling methods on a non-functional object.

Also adds a per-request failure flag to skip repeated init attempts and
a Site Health warning to guide admins toward fixing or disabling caching.
Copilot AI review requested due to automatic review settings February 24, 2026 17:38
@pfefferle pfefferle added the Bug Something isn't working label Feb 24, 2026
@pfefferle pfefferle self-assigned this Feb 24, 2026
@pfefferle pfefferle requested a review from a team February 24, 2026 17:38
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical crash that occurs on servers where WordPress falls back to FTP filesystem access instead of direct file access. The issue (#2972) manifested as fatal errors when the plugin attempted to cache remote avatars, causing entire pages to crash with "There has been a critical error on this website."

Changes:

  • Centralized filesystem access in Cache\File with proper handling of WP_Filesystem() failures
  • Added Site Health warning to inform admins when direct filesystem access is unavailable
  • Removed duplicated filesystem code from Cache\Media by leveraging inherited methods

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
includes/cache/class-file.php Added centralized get_filesystem() and delete_directory() helpers with failure handling and per-request failure flag; refactored existing filesystem initialization calls to use the new helpers
includes/cache/class-media.php Removed duplicated cache_url() method in favor of inherited get_or_cache(); simplified invalidate_comment() to use centralized delete_directory()
includes/class-attachments.php Fixed filesystem initialization to properly handle WP_Filesystem() failure by nulling the global on failure
includes/wp-admin/class-health-check.php Added new test_filesystem() health check that warns administrators when direct filesystem access is unavailable and provides guidance on fixing or disabling caching
.github/changelog/fix-filesystem-graceful-failure Added changelog entry for patch-level bug fix

Skip the test when ACTIVITYPUB_DISABLE_REMOTE_CACHE is set, and null
the broken $wp_filesystem global on failure to avoid side effects for
other health checks running in the same request.
WordPress core uses native PHP functions (rename, copy, etc.) for file
operations in the uploads directory — not WP_Filesystem. WP_Filesystem
checks write access to ABSPATH and falls back to FTP when that fails,
even though the uploads directory itself is writable.

This removes all WP_Filesystem usage from cache, attachments, and CLI
code, matching how core handles files in the same directory. This
eliminates the FTP fallback crash entirely rather than just handling
it gracefully.

The health check now tests uploads directory writability instead of
WP_Filesystem availability.
Instantiate WP_Filesystem_Direct explicitly to get WordPress's own
filesystem methods (move, copy, rmdir) without the FTP fallback that
WP_Filesystem() triggers. Cleaner than raw rename/copy/rmdir calls
and leverages WP_Filesystem_Direct's recursive rmdir.
@pfefferle pfefferle requested a review from jeherve February 25, 2026 08:01
Copy link
Member

@jeherve jeherve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good to me. 🚢

@pfefferle pfefferle merged commit 5860cd1 into trunk Feb 25, 2026
10 checks passed
@pfefferle pfefferle deleted the fix/filesystem-graceful-failure branch February 25, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crashes Wordpress - attempting to use FTP for avatars for some reason

3 participants