Codeinwp / Codeinwp/optimole-wp
Array-valued AJAX action causes `strpos()` TypeError
- Dominant language
- PHP
- Stars
- 72
- Forks
- 14
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 15
Description
Summary
A logged-out AJAX request whose action parameter is submitted as an array can cause Optimole to terminate with a strpos() TypeError during startup.
Expected behavior: the request is handled or rejected without an Optimole fatal error.
Actual behavior: Optimole passes the array value to strpos(), producing a fatal error before the request completes.
Impact: affected frontend AJAX requests fail with a 500 response while Optimole is enabled and connected.
Customer context
- Product / area: Optimole WordPress plugin, AJAX request detection
- Version: 4.2.12
- Environment: WordPress 7.1, PHP 8.3.33
- Integration / third party: Not provided
- Reported error / symptom:
strpos(): Argument #1 ($haystack) must be of type string, array given - Impact: 20 telemetry occurrences across 2 production sites between 2026-09-12 08:35 and 15:01 UTC.
Reproduction notes
Reported production context: frontend requests on Optimole 4.2.12, WordPress 7.1, and PHP 8.3.33.
- Enable and connect Optimole.
- Send a logged-out AJAX request with an array-valued
actionparameter, such asaction[]=wpmdb. - During Optimole startup, the request reaches AJAX detection and the reported
strpos()TypeError occurs.
Direct PHP evaluation of the reported expression with an array argument produced the same TypeError. A full WordPress request reproduction was not run.
Diagnosis
Conclusion
Production telemetry identifies a TypeError at Optml_Manager::is_ajax_request(). The inspected v4.2.12 source passes $_REQUEST['action'] directly to strpos() after only checking that the key exists. PHP represents action[]=wpmdb as an array, which matches the reported argument type and produces the fatal on PHP 8.3.
Where this likely occurs
- Frontend AJAX startup path in
inc/manager.php—Optml_Manager::should_replace()lines 296-370 callsOptml_Manager::is_ajax_request()at lines 309-311. inc/manager.php—Optml_Manager::is_ajax_request()lines 377-401 reachesstrpos( $_REQUEST['action'], 'wpmdb' )at line 396 without a scalar-type check.- The call is reachable for logged-out AJAX requests:
inc/manager.php—Optml_Manager::is_ajax_request()lines 382-400 returns before this expression only when the user is logged in, AJAX is unavailable, or the request is not AJAX. - The expression exists in release tag
v4.2.12(ce4220e93d2a9cf83aa4351540df4e9255d028f3). Git blame attributes the line to02df07746from 2019; no earlier working release boundary was established.
Engineering notes
- The confirmed path is limited to AJAX requests while the visitor is logged out and Optimole is connected and enabled; these are the observed guards in the inspected code.
- A request such as
action[]=wpmdbis a plausible trigger because PHP converts bracketed request keys into arrays. WordPress core behavior after plugin initialization was not inspected locally; the telemetry and code order establish that Optimole evaluates this parameter during startup. - This is distinct from the four file/class loading crashes in the same telemetry batch. Those traces were assessed independently and are not represented by this entry.
Test coverage status
phpunit.xml registers the tests/ PHPUnit suite. No relevant coverage was found during inspection for Optml_Manager::is_ajax_request(), an array-valued $_REQUEST['action'], or the wpmdb exclusion. tests/test-cache-header.php is manager-adjacent but covers unrelated cache-header behavior.
What to verify or explore next
- May be worth reproducing against a WordPress AJAX request with
action[]=wpmdbon supported PHP versions. - May be worth running the PHPUnit suite and checking whether request-shape coverage exists outside the inspected
tests/paths. - May be worth confirming behavior with non-
wpmdbarray action values and with logged-in versus logged-out requests.
Unknowns / follow-up
- Telemetry does not retain the original request payload, so the exact submitted array shape is unavailable.
- No precise open GitHub issue was found through repository issue search.
Confidence
Confidence: 97/100
v4.2.12 passes an array-capable $_REQUEST['action'] value directly to strpos() on a reachable logged-out AJAX path, matching the production TypeError. The other four crashes reference files or an SDK class present and mapped in the inspected v4.2.11 source, so the available evidence favors incomplete or mixed deployments rather than repository defects.
Crash telemetry
| Occurrences | 20 |
| Distinct sites | 2 |
| First seen | 2026-09-12 08:35 UTC |
| Last seen | 2026-09-12 15:01 UTC |
| Crash location | product:inc/manager.php:396 |
| Request context | frontend |
| Inside Themeisle SDK | no |
| Product versions | 4.2.12 |
| WP versions | 7.1 |
| PHP versions | 8.3.33 |
| SDK versions | 3.3.61 |
Source: automated crash report — optimole-wp, fingerprint dc1c56b497c01bc567b15f51e34401fc
Generated by bug-report-triage (ID: bug-report-triage_6aa63c5159bf59.34701292)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.