Skip to content

Runtime checks return HTTP 400 / body 0 while admin UI reports no errors #1445

Open

Description

@reklamniagent-pirat

Status: reproducible upstream/tooling incident; no evidence of an EAA plugin defect.

Environment
Plugin Check 2.1.0;
WordPress 7.0.4 on the first environment;
PHP 8.2.33, FPM/FastCGI, Apache 2.4.68 on clean.pirat.okinawa;
a second independent WordPress environment configured for PHP 8.3 on pirat.okinawa;
WordPress admin Plugin Check UI;
category: Performance.
Both sites are disposable QA installations. The report intentionally excludes credentials, nonces, cookies and response headers.

Steps to reproduce
Install and activate Plugin Check 2.1.0.
Select a plugin for which Performance discovery includes runtime checks. The issue was reproduced with P-I-R-@-T EAA Accessibility Auditor 0.8.6 on both environments and with WooCommerce on the PHP 8.2 environment.
Select only the Performance category.
Run Plugin Check while monitoring POST requests to /wp-admin/admin-ajax.php.
Expected result
Every check returned by plugin_check_get_checks_to_run is executed. A success notice is rendered only when every discovery, setup, check and cleanup request succeeds.

Actual result
Discovery returns HTTP 200 and these eight checks:

performant_wp_query_params;
enqueued_scripts_in_footer;
enqueued_resources;
enqueued_scripts_size;
enqueued_styles_size;
enqueued_styles_scope;
enqueued_scripts_scope;
non_blocking_scripts.
plugin_check_set_up_environment returns HTTP 200 with Runtime environment setup successful.. The first three static checks return HTTP 200. Each of the five runtime checks then returns HTTP 400 with the response body 0:

enqueued_scripts_size;
enqueued_styles_size;
enqueued_styles_scope;
enqueued_scripts_scope;
non_blocking_scripts.
plugin_check_clean_up_environment subsequently returns HTTP 200 with Runtime environment cleanup successful..

The admin UI may still render Checks complete. No errors found. because the individual failed check requests are caught without being reflected in the final completion state.

Cross-checks
The EAA plugin's three static Performance checks complete with no findings before the runtime requests fail.
WooCommerce reproduces the same five HTTP 400 / 0 runtime failures. Its static checks execute normally and return WooCommerce-specific findings, demonstrating that static analysis and result transport are working.
Hello Dolly is not a runtime comparison: its Performance discovery returns only the three static checks and setup reports No runtime checks, runtime environment was not setup..
The exact EAA sequence reproduces on the PHP 8.2 and PHP 8.3 WordPress installations.
Impact
The visible success state can be a false positive: five expected runtime checks were not executed successfully. Consumers should treat this combination as indeterminate, not as a pass.

Diagnostic interpretation
The response body 0 is the WordPress AJAX fallback observed when the requested action has no registered callback in that request. Since discovery, setup and cleanup succeed while every isolated runtime check fails identically across plugins and environments, the evidence points to the Plugin Check runtime bootstrap rather than to an individual checked plugin.

Thanks for repair
Ilja HYnek

Activity

  1. sanketio commented on Aug 31, 2026

    @sanketio

    Reproduced on WP 7.1 / PHP 8.3. The runtime check requests switch the DB prefix to wp_pc_ on muplugins_loaded; wp_pc_users only contains the plugincheck user created by wp_install(), so the admin's cookie no longer validates and admin-ajax.php returns 0/400 before the handler runs. Static checks are unaffected because the prefix is only switched when a runtime check is in the request.

    Should runtime checks execute as an anonymous visitor, or as the acting admin? An authenticated admin adds the admin bar's scripts and styles to what enqueued_scripts_size and enqueued_*_scope measure, so it changes results.

  2. sanketio commented on Aug 31, 2026

    @sanketio

    #1457 covers only the reporting half — the UI no longer claims "No errors found" when a check request fails. The 400 itself is untouched; I'll follow up with a second PR once the question above is settled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions