-
Notifications
You must be signed in to change notification settings - Fork 322
Description
Describe the bug
Environment
- WordPress: 6.9
- PHP: 8.3.16
- ElasticPress: 5.3.2
- Occurs in wp-admin (Plugins page, Dashboard notices)
❌ The problem
A fatal error occurs in wp-admin due to a strict type hint in
ElasticPress\QueryLogger::maybe_add_notice() when the $notices argument is null:
PHP Fatal error: Uncaught TypeError:
ElasticPress\QueryLogger::maybe_add_notice(): Argument #1 ($notices)
must be of type array, null given
Stack trace (trimmed):
ElasticPress\QueryLogger->maybe_add_notice()
WP_Hook->apply_filters()
ElasticPress\AdminNotices->get_notices()
ElasticPress\Dashboard\maybe_notice()
🔍 Root cause
In AdminNotices::get_notices():
$notices = apply_filters( 'ep_admin_notices', $this->notices );
$this->notices can be null at runtime (not initialized yet), so:
apply_filters()starts withnull- The filter chain passes
null QueryLogger::maybe_add_notice()is strictly type-hinted as:
public function maybe_add_notice( array $notices ): array- PHP throws a TypeError before the method body executes
This causes a fatal error and makes the entire wp-admin inaccessible.
✅ Confirmed fix
Normalizing the input inside maybe_add_notice() resolves the issue completely:
public function maybe_add_notice( $notices ): array {
$notices = is_array( $notices ) ? $notices : [];
...
}
This is safe, backward-compatible, and aligns with WordPress’ filter behavior
(filters may receive null).
🎯 Expected behavior
- wp-admin should never fatal if a filter returns null
- ElasticPress should defensively handle unexpected filter input
- The notices system should degrade gracefully
🧪 Status
- ✅ Issue reproduced
- ✅ Root cause identified
- ✅ Fix verified in production
- ❌ Current versions crash on PHP 8+ without patch
Steps to Reproduce
- Install and activate ElasticPress on a WordPress site.
- Run the site on PHP 8.3.16.
- Ensure ElasticPress admin notices are enabled (default behavior).
- Open wp-admin (for example: Plugins → Installed Plugins or Dashboard).
- WordPress executes
ElasticPress\AdminNotices::get_notices(). $this->noticesisnull, soapply_filters( 'ep_admin_notices', null )is executed.- The filter chain reaches
QueryLogger::maybe_add_notice()which is strictly typed as:
public function maybe_add_notice( array $notices ): array - PHP throws a fatal error:
TypeError: Argument #1 ($notices) must be of type array, null given - wp-admin becomes inaccessible due to the fatal error.
Screenshots, screen recording, code snippet
No response
Environment information
- WordPress: 6.9
- PHP: 8.3.16
- ElasticPress: 5.3.2
WordPress and ElasticPress information
Failed Queries
WordPress
WordPress Environment
wp_version: 6.9
home_url: https://blog.backyardbrains.com
site_url: https://blog.backyardbrains.com
is_multisite: false
theme: Backyard Brains (1.0)
plugins: 301 Redirects (2.79), Akismet Anti-spam: Spam Protection (5.6), Better Search Replace (1.4.10), Database Manager - WP Adminer (4.1.1), ElasticPress (5.3.2), EmbedPress (4.4.8), Embeds for YouTube (5.4), Gallery Custom Links (2.2.8), Image Regenerate & Select Crop (8.1.2), Login by Auth0 (4.6.2), MC4WP: Mailchimp for WordPress (4.10.3), MediaElement.js - HTML5 Audio and Video (4.2.8), Post Gallery (2.3.12), Really Simple Security (9.3.5), Redis Object Cache (2.5.4), Simple Audio Player (0.2), Simple Lightbox (2.9.4), Simple Local Avatars (2.8.3), Site Kit by Google (1.153.0), SVG Support (2.5.14), UpdraftPlus - Backup/Restore (1.25.9), Wordfence Security (8.1.4), WP-PageNavi (2.94.5), WP Migrate Lite (2.7.3), and Yoast SEO (26.7)
revisions: all
Server Environment
php_version: 8.3.16
memory_limit: 40M
timeout: 30
Indexable Content
Backyard Brains — https://blog.backyardbrains.com
post_count: 440
page_count: 4
post_meta_keys: 0
page_meta_keys: 0
total-all-post-types: 0
distinct-meta-keys:
ElasticPress
Settings
host: https://search.backyardbrains.com/
index_prefix:
language: site-default
per_page: 350
network_active: false
Timeouts
request_timeout: 5
index_document_timeout: 15
bulk_request_timeout: 30
Elasticsearch Indices
blogbackyardbrainscom-post-1
health: yellow
status: open
index: blogbackyardbrainscom-post-1
uuid: zQV06eKlS2yl9LYLpleR_g
pri: 5
rep: 1
docs.count: 444
docs.deleted: 30
store.size: 6.4mb
pri.store.size: 6.4mb
dataset.size: 6.4mb
total_fields_limit: 5000
analyzer_language: english
stop_language: english
snowball_language: English
Last Sync
2025/03/06 11:45:21 am
method: WP Dashboard
is_full_sync: Yes
end_date_time: 2025/03/06 11:45:34 am
total_time: 0 hours, 0 minutes, 14 seconds
total: 443
synced: 443
skipped: 0
failed: 0
errors: array (
)
trigger:
final_status: success
Feature Settings
Custom Search Results
active: true
force_inactive: false
Filters
active: true
force_inactive: false
match_type: all
Post Search
active: true
decaying_enabled: 1
force_inactive: false
highlight_enabled: 1
highlight_excerpt: 1
highlight_tag: strong
synonyms_editor_mode: simple
synonyms:
# Defined synonyms.
runner, running shoe, sneaker, tennis shoe, trainerDefined hyponyms.
blue => blue, aqua, azure, cerulean, cyan, ultramarine
Defined replacements.
supposably => supposedly
flustrated => flustered, frustrated
intensive purposes => intents and purposes
weighting: array (
)
Related Posts
active: true
force_inactive: false
Code of Conduct
- I agree to follow this project's Code of Conduct